/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenSimulator Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.XMREngine; using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Text; using System.Text.RegularExpressions; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; namespace OpenSim.Region.ScriptEngine.XMREngine { /** * @brief This class is used to catalog the code emit routines based on a key string * The key string has the two types (eg, "integer", "rotation") and the operator (eg, "*", "!=") */ public delegate void BinOpStrEmitBO (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result); public class BinOpStr { public static readonly Dictionary defined = DefineBinOps (); public Type outtype; // type of result of computation public BinOpStrEmitBO emitBO; // how to compute result public bool rmwOK; // is the = form valid? public BinOpStr (Type outtype, BinOpStrEmitBO emitBO) { this.outtype = outtype; this.emitBO = emitBO; this.rmwOK = false; } public BinOpStr (Type outtype, BinOpStrEmitBO emitBO, bool rmwOK) { this.outtype = outtype; this.emitBO = emitBO; this.rmwOK = rmwOK; } private static TokenTypeBool tokenTypeBool = new TokenTypeBool (null); private static TokenTypeChar tokenTypeChar = new TokenTypeChar (null); private static TokenTypeFloat tokenTypeFloat = new TokenTypeFloat (null); private static TokenTypeInt tokenTypeInt = new TokenTypeInt (null); private static TokenTypeList tokenTypeList = new TokenTypeList (null); private static TokenTypeRot tokenTypeRot = new TokenTypeRot (null); private static TokenTypeStr tokenTypeStr = new TokenTypeStr (null); private static TokenTypeVec tokenTypeVec = new TokenTypeVec (null); private static MethodInfo stringAddStringMethInfo = ScriptCodeGen.GetStaticMethod (typeof (string), "Concat", new Type[] { typeof (string), typeof (string) }); private static MethodInfo stringCmpStringMethInfo = ScriptCodeGen.GetStaticMethod (typeof (string), "Compare", new Type[] { typeof (string), typeof (string) }); private static MethodInfo infoMethListAddFloat = GetBinOpsMethod ("MethListAddFloat", new Type[] { typeof (LSL_List), typeof (double) }); private static MethodInfo infoMethListAddInt = GetBinOpsMethod ("MethListAddInt", new Type[] { typeof (LSL_List), typeof (int) }); private static MethodInfo infoMethListAddKey = GetBinOpsMethod ("MethListAddKey", new Type[] { typeof (LSL_List), typeof (string) }); private static MethodInfo infoMethListAddRot = GetBinOpsMethod ("MethListAddRot", new Type[] { typeof (LSL_List), typeof (LSL_Rotation) }); private static MethodInfo infoMethListAddStr = GetBinOpsMethod ("MethListAddStr", new Type[] { typeof (LSL_List), typeof (string) }); private static MethodInfo infoMethListAddVec = GetBinOpsMethod ("MethListAddVec", new Type[] { typeof (LSL_List), typeof (LSL_Vector) }); private static MethodInfo infoMethListAddList = GetBinOpsMethod ("MethListAddList", new Type[] { typeof (LSL_List), typeof (LSL_List) }); private static MethodInfo infoMethFloatAddList = GetBinOpsMethod ("MethFloatAddList", new Type[] { typeof (double), typeof (LSL_List) }); private static MethodInfo infoMethIntAddList = GetBinOpsMethod ("MethIntAddList", new Type[] { typeof (int), typeof (LSL_List) }); private static MethodInfo infoMethKeyAddList = GetBinOpsMethod ("MethKeyAddList", new Type[] { typeof (string), typeof (LSL_List) }); private static MethodInfo infoMethRotAddList = GetBinOpsMethod ("MethRotAddList", new Type[] { typeof (LSL_Rotation), typeof (LSL_List) }); private static MethodInfo infoMethStrAddList = GetBinOpsMethod ("MethStrAddList", new Type[] { typeof (string), typeof (LSL_List) }); private static MethodInfo infoMethVecAddList = GetBinOpsMethod ("MethVecAddList", new Type[] { typeof (LSL_Vector), typeof (LSL_List) }); private static MethodInfo infoMethListEqList = GetBinOpsMethod ("MethListEqList", new Type[] { typeof (LSL_List), typeof (LSL_List) }); private static MethodInfo infoMethListNeList = GetBinOpsMethod ("MethListNeList", new Type[] { typeof (LSL_List), typeof (LSL_List) }); private static MethodInfo infoMethRotEqRot = GetBinOpsMethod ("MethRotEqRot", new Type[] { typeof (LSL_Rotation), typeof (LSL_Rotation) }); private static MethodInfo infoMethRotNeRot = GetBinOpsMethod ("MethRotNeRot", new Type[] { typeof (LSL_Rotation), typeof (LSL_Rotation) }); private static MethodInfo infoMethRotAddRot = GetBinOpsMethod ("MethRotAddRot", new Type[] { typeof (LSL_Rotation), typeof (LSL_Rotation) }); private static MethodInfo infoMethRotSubRot = GetBinOpsMethod ("MethRotSubRot", new Type[] { typeof (LSL_Rotation), typeof (LSL_Rotation) }); private static MethodInfo infoMethRotMulRot = GetBinOpsMethod ("MethRotMulRot", new Type[] { typeof (LSL_Rotation), typeof (LSL_Rotation) }); private static MethodInfo infoMethRotDivRot = GetBinOpsMethod ("MethRotDivRot", new Type[] { typeof (LSL_Rotation), typeof (LSL_Rotation) }); private static MethodInfo infoMethVecEqVec = GetBinOpsMethod ("MethVecEqVec", new Type[] { typeof (LSL_Vector), typeof (LSL_Vector) }); private static MethodInfo infoMethVecNeVec = GetBinOpsMethod ("MethVecNeVec", new Type[] { typeof (LSL_Vector), typeof (LSL_Vector) }); private static MethodInfo infoMethVecAddVec = GetBinOpsMethod ("MethVecAddVec", new Type[] { typeof (LSL_Vector), typeof (LSL_Vector) }); private static MethodInfo infoMethVecSubVec = GetBinOpsMethod ("MethVecSubVec", new Type[] { typeof (LSL_Vector), typeof (LSL_Vector) }); private static MethodInfo infoMethVecMulVec = GetBinOpsMethod ("MethVecMulVec", new Type[] { typeof (LSL_Vector), typeof (LSL_Vector) }); private static MethodInfo infoMethVecModVec = GetBinOpsMethod ("MethVecModVec", new Type[] { typeof (LSL_Vector), typeof (LSL_Vector) }); private static MethodInfo infoMethVecMulFloat = GetBinOpsMethod ("MethVecMulFloat", new Type[] { typeof (LSL_Vector), typeof (double) }); private static MethodInfo infoMethFloatMulVec = GetBinOpsMethod ("MethFloatMulVec", new Type[] { typeof (double), typeof (LSL_Vector) }); private static MethodInfo infoMethVecDivFloat = GetBinOpsMethod ("MethVecDivFloat", new Type[] { typeof (LSL_Vector), typeof (double) }); private static MethodInfo infoMethVecMulInt = GetBinOpsMethod ("MethVecMulInt", new Type[] { typeof (LSL_Vector), typeof (int) }); private static MethodInfo infoMethIntMulVec = GetBinOpsMethod ("MethIntMulVec", new Type[] { typeof (int), typeof (LSL_Vector) }); private static MethodInfo infoMethVecDivInt = GetBinOpsMethod ("MethVecDivInt", new Type[] { typeof (LSL_Vector), typeof (int) }); private static MethodInfo infoMethVecMulRot = GetBinOpsMethod ("MethVecMulRot", new Type[] { typeof (LSL_Vector), typeof (LSL_Rotation) }); private static MethodInfo infoMethVecDivRot = GetBinOpsMethod ("MethVecDivRot", new Type[] { typeof (LSL_Vector), typeof (LSL_Rotation) }); private static MethodInfo GetBinOpsMethod (string name, Type[] types) { return ScriptCodeGen.GetStaticMethod (typeof (BinOpStr), name, types); } /** * @brief Create a dictionary for processing binary operators. * This tells us, for a given type, an operator and another type, * is the operation permitted, and if so, what is the type of the result? * The key is , * where and are strings returned by (TokenType...).ToString() * and is string returned by (TokenKw...).ToString() * The value is a BinOpStr struct giving the resultant type and a method to generate the code. */ private static Dictionary DefineBinOps () { Dictionary bos = new Dictionary (); string[] booltypes = new string[] { "bool", "char", "float", "integer", "key", "list", "string" }; /* * Get the && and || all out of the way... * Simply cast their left and right operands to boolean then process. */ for (int i = 0; i < booltypes.Length; i ++) { for (int j = 0; j < booltypes.Length; j ++) { bos.Add (booltypes[i] + "&&" + booltypes[j], new BinOpStr (typeof (bool), BinOpStrAndAnd)); bos.Add (booltypes[i] + "||" + booltypes[j], new BinOpStr (typeof (bool), BinOpStrOrOr)); } } /* * Pound through all the other combinations we support. */ // boolean : somethingelse DefineBinOpsBoolX (bos, "bool"); DefineBinOpsBoolX (bos, "char"); DefineBinOpsBoolX (bos, "float"); DefineBinOpsBoolX (bos, "integer"); DefineBinOpsBoolX (bos, "key"); DefineBinOpsBoolX (bos, "list"); DefineBinOpsBoolX (bos, "string"); // stuff with chars DefineBinOpsChar (bos); // somethingelse : boolean DefineBinOpsXBool (bos, "char"); DefineBinOpsXBool (bos, "float"); DefineBinOpsXBool (bos, "integer"); DefineBinOpsXBool (bos, "key"); DefineBinOpsXBool (bos, "list"); DefineBinOpsXBool (bos, "string"); // float : somethingelse DefineBinOpsFloatX (bos, "float"); DefineBinOpsFloatX (bos, "integer"); // integer : float DefineBinOpsXFloat (bos, "integer"); // anything else with integers DefineBinOpsInteger (bos); // key : somethingelse DefineBinOpsKeyX (bos, "key"); DefineBinOpsKeyX (bos, "string"); // string : key DefineBinOpsXKey (bos, "string"); // things with lists DefineBinOpsList (bos); // things with rotations DefineBinOpsRotation (bos); // things with strings DefineBinOpsString (bos); // things with vectors DefineBinOpsVector (bos); // Contrary to some beliefs, scripts do things like string+integer and integer+string bos.Add ("bool+string", new BinOpStr (typeof (string), BinOpStrStrAddStr)); bos.Add ("char+string", new BinOpStr (typeof (string), BinOpStrStrAddStr)); bos.Add ("float+string", new BinOpStr (typeof (string), BinOpStrStrAddStr)); bos.Add ("integer+string", new BinOpStr (typeof (string), BinOpStrStrAddStr)); bos.Add ("string+bool", new BinOpStr (typeof (string), BinOpStrStrAddStr, true)); bos.Add ("string+char", new BinOpStr (typeof (string), BinOpStrStrAddStr, true)); bos.Add ("string+float", new BinOpStr (typeof (string), BinOpStrStrAddStr, true)); bos.Add ("string+integer", new BinOpStr (typeof (string), BinOpStrStrAddStr, true)); // Now for our final slight-of-hand, we're going to scan through all those. // And wherever we see an 'integer' in the key, we are going to make another // entry with 'bool', as we want to accept a bool as having a value of 0 or 1. // This lets us do things like 3.5 * (x > 0). Dictionary bos2 = new Dictionary (); foreach (KeyValuePair kvp in bos) { string key = kvp.Key; BinOpStr val = kvp.Value; bos2.Add (key, val); } Regex wordReg = new Regex("\\w+"); Regex opReg = new Regex("\\W+"); foreach (KeyValuePair kvp in bos) { string key = kvp.Key; BinOpStr val = kvp.Value; MatchCollection matches = wordReg.Matches(key); if (matches.Count != 2) continue; Match opM = opReg.Match(key); if (!opM.Success) continue; string left = matches[0].Value; string right = matches[1].Value; string op = opM.Value; string key2; if (left == "integer" && right == "integer") { key2 = "bool"+op+"bool"; if (!bos2.ContainsKey (key2)) bos2.Add (key2, val); key2 = "bool"+op+"integer"; if (!bos2.ContainsKey (key2)) bos2.Add (key2, val); key2 = "integer"+op+"bool"; if (!bos2.ContainsKey (key2)) bos2.Add (key2, val); } else { key2 = key.Replace("integer", "bool"); if (!bos2.ContainsKey (key2)) bos2.Add (key2, val); } } return bos2; } private static void DefineBinOpsBoolX (Dictionary bos, string x) { bos.Add ("bool|" + x, new BinOpStr (typeof (int), BinOpStrBoolOrX)); bos.Add ("bool^" + x, new BinOpStr (typeof (int), BinOpStrBoolXorX)); bos.Add ("bool&" + x, new BinOpStr (typeof (int), BinOpStrBoolAndX)); bos.Add ("bool==" + x, new BinOpStr (typeof (bool), BinOpStrBoolEqX)); bos.Add ("bool!=" + x, new BinOpStr (typeof (bool), BinOpStrBoolNeX)); } private static void DefineBinOpsXBool (Dictionary bos, string x) { bos.Add (x + "|bool", new BinOpStr (typeof (int), BinOpStrBoolOrX)); bos.Add (x + "^bool", new BinOpStr (typeof (int), BinOpStrBoolXorX)); bos.Add (x + "&bool", new BinOpStr (typeof (int), BinOpStrBoolAndX)); bos.Add (x + "==bool", new BinOpStr (typeof (bool), BinOpStrBoolEqX)); bos.Add (x + "!=bool", new BinOpStr (typeof (bool), BinOpStrBoolNeX)); } private static void DefineBinOpsFloatX (Dictionary bos, string x) { bos.Add ("float==" + x, new BinOpStr (typeof (bool), BinOpStrFloatEqX)); bos.Add ("float!=" + x, new BinOpStr (typeof (bool), BinOpStrFloatNeX)); bos.Add ("float<" + x, new BinOpStr (typeof (bool), BinOpStrFloatLtX)); bos.Add ("float<=" + x, new BinOpStr (typeof (bool), BinOpStrFloatLeX)); bos.Add ("float>" + x, new BinOpStr (typeof (bool), BinOpStrFloatGtX)); bos.Add ("float>=" + x, new BinOpStr (typeof (bool), BinOpStrFloatGeX)); bos.Add ("float+" + x, new BinOpStr (typeof (double), BinOpStrFloatAddX, true)); bos.Add ("float-" + x, new BinOpStr (typeof (double), BinOpStrFloatSubX, true)); bos.Add ("float*" + x, new BinOpStr (typeof (double), BinOpStrFloatMulX, true)); bos.Add ("float/" + x, new BinOpStr (typeof (double), BinOpStrFloatDivX, true)); bos.Add ("float%" + x, new BinOpStr (typeof (double), BinOpStrFloatModX, true)); } private static void DefineBinOpsXFloat (Dictionary bos, string x) { bos.Add (x + "==float", new BinOpStr (typeof (bool), BinOpStrXEqFloat)); bos.Add (x + "!=float", new BinOpStr (typeof (bool), BinOpStrXNeFloat)); bos.Add (x + "float", new BinOpStr (typeof (bool), BinOpStrXGtFloat)); bos.Add (x + ">=float", new BinOpStr (typeof (bool), BinOpStrXGeFloat)); bos.Add (x + "+float", new BinOpStr (typeof (double), BinOpStrXAddFloat, true)); bos.Add (x + "-float", new BinOpStr (typeof (double), BinOpStrXSubFloat, true)); bos.Add (x + "*float", new BinOpStr (typeof (double), BinOpStrXMulFloat, true)); bos.Add (x + "/float", new BinOpStr (typeof (double), BinOpStrXDivFloat, true)); bos.Add (x + "%float", new BinOpStr (typeof (double), BinOpStrXModFloat, true)); } private static void DefineBinOpsChar (Dictionary bos) { bos.Add ("char==char", new BinOpStr (typeof (bool), BinOpStrCharEqChar)); bos.Add ("char!=char", new BinOpStr (typeof (bool), BinOpStrCharNeChar)); bos.Add ("charchar", new BinOpStr (typeof (bool), BinOpStrCharGtChar)); bos.Add ("char>=char", new BinOpStr (typeof (bool), BinOpStrCharGeChar)); bos.Add ("char+integer", new BinOpStr (typeof (char), BinOpStrCharAddInt, true)); bos.Add ("char-integer", new BinOpStr (typeof (char), BinOpStrCharSubInt, true)); bos.Add ("char-char", new BinOpStr (typeof (int), BinOpStrCharSubChar)); } private static void DefineBinOpsInteger (Dictionary bos) { bos.Add ("integer==integer", new BinOpStr (typeof (bool), BinOpStrIntEqInt)); bos.Add ("integer!=integer", new BinOpStr (typeof (bool), BinOpStrIntNeInt)); bos.Add ("integerinteger", new BinOpStr (typeof (bool), BinOpStrIntGtInt)); bos.Add ("integer>=integer", new BinOpStr (typeof (bool), BinOpStrIntGeInt)); bos.Add ("integer|integer", new BinOpStr (typeof (int), BinOpStrIntOrInt, true)); bos.Add ("integer^integer", new BinOpStr (typeof (int), BinOpStrIntXorInt, true)); bos.Add ("integer&integer", new BinOpStr (typeof (int), BinOpStrIntAndInt, true)); bos.Add ("integer+integer", new BinOpStr (typeof (int), BinOpStrIntAddInt, true)); bos.Add ("integer-integer", new BinOpStr (typeof (int), BinOpStrIntSubInt, true)); bos.Add ("integer*integer", new BinOpStr (typeof (int), BinOpStrIntMulInt, true)); bos.Add ("integer/integer", new BinOpStr (typeof (int), BinOpStrIntDivInt, true)); bos.Add ("integer%integer", new BinOpStr (typeof (int), BinOpStrIntModInt, true)); bos.Add ("integer<>integer", new BinOpStr (typeof (int), BinOpStrIntShrInt, true)); } private static void DefineBinOpsKeyX (Dictionary bos, string x) { bos.Add ("key==" + x, new BinOpStr (typeof (bool), BinOpStrKeyEqX)); bos.Add ("key!=" + x, new BinOpStr (typeof (bool), BinOpStrKeyNeX)); } private static void DefineBinOpsXKey (Dictionary bos, string x) { bos.Add (x + "==key", new BinOpStr (typeof (bool), BinOpStrKeyEqX)); bos.Add (x + "!=key", new BinOpStr (typeof (bool), BinOpStrKeyNeX)); } private static void DefineBinOpsList (Dictionary bos) { bos.Add ("list+float", new BinOpStr (typeof (LSL_List), BinOpStrListAddFloat, true)); bos.Add ("list+integer", new BinOpStr (typeof (LSL_List), BinOpStrListAddInt, true)); bos.Add ("list+key", new BinOpStr (typeof (LSL_List), BinOpStrListAddKey, true)); bos.Add ("list+list", new BinOpStr (typeof (LSL_List), BinOpStrListAddList, true)); bos.Add ("list+rotation", new BinOpStr (typeof (LSL_List), BinOpStrListAddRot, true)); bos.Add ("list+string", new BinOpStr (typeof (LSL_List), BinOpStrListAddStr, true)); bos.Add ("list+vector", new BinOpStr (typeof (LSL_List), BinOpStrListAddVec, true)); bos.Add ("float+list", new BinOpStr (typeof (LSL_List), BinOpStrFloatAddList)); bos.Add ("integer+list", new BinOpStr (typeof (LSL_List), BinOpStrIntAddList)); bos.Add ("key+list", new BinOpStr (typeof (LSL_List), BinOpStrKeyAddList)); bos.Add ("rotation+list", new BinOpStr (typeof (LSL_List), BinOpStrRotAddList)); bos.Add ("string+list", new BinOpStr (typeof (LSL_List), BinOpStrStrAddList)); bos.Add ("vector+list", new BinOpStr (typeof (LSL_List), BinOpStrVecAddList)); bos.Add ("list==list", new BinOpStr (typeof (bool), BinOpStrListEqList)); bos.Add ("list!=list", new BinOpStr (typeof (int), BinOpStrListNeList)); } // all operations allowed by LSL_Rotation definition private static void DefineBinOpsRotation (Dictionary bos) { bos.Add ("rotation==rotation", new BinOpStr (typeof (bool), BinOpStrRotEqRot)); bos.Add ("rotation!=rotation", new BinOpStr (typeof (bool), BinOpStrRotNeRot)); bos.Add ("rotation+rotation", new BinOpStr (typeof (LSL_Rotation), BinOpStrRotAddRot, true)); bos.Add ("rotation-rotation", new BinOpStr (typeof (LSL_Rotation), BinOpStrRotSubRot, true)); bos.Add ("rotation*rotation", new BinOpStr (typeof (LSL_Rotation), BinOpStrRotMulRot, true)); bos.Add ("rotation/rotation", new BinOpStr (typeof (LSL_Rotation), BinOpStrRotDivRot, true)); } private static void DefineBinOpsString (Dictionary bos) { bos.Add ("string==string", new BinOpStr (typeof (bool), BinOpStrStrEqStr)); bos.Add ("string!=string", new BinOpStr (typeof (bool), BinOpStrStrNeStr)); bos.Add ("stringstring", new BinOpStr (typeof (bool), BinOpStrStrGtStr)); bos.Add ("string>=string", new BinOpStr (typeof (bool), BinOpStrStrGeStr)); bos.Add ("string+string", new BinOpStr (typeof (string), BinOpStrStrAddStr, true)); } // all operations allowed by LSL_Vector definition private static void DefineBinOpsVector (Dictionary bos) { bos.Add ("vector==vector", new BinOpStr (typeof (bool), BinOpStrVecEqVec)); bos.Add ("vector!=vector", new BinOpStr (typeof (bool), BinOpStrVecNeVec)); bos.Add ("vector+vector", new BinOpStr (typeof (LSL_Vector), BinOpStrVecAddVec, true)); bos.Add ("vector-vector", new BinOpStr (typeof (LSL_Vector), BinOpStrVecSubVec, true)); bos.Add ("vector*vector", new BinOpStr (typeof (double), BinOpStrVecMulVec)); bos.Add ("vector%vector", new BinOpStr (typeof (LSL_Vector), BinOpStrVecModVec, true)); bos.Add ("vector*float", new BinOpStr (typeof (LSL_Vector), BinOpStrVecMulFloat, true)); bos.Add ("float*vector", new BinOpStr (typeof (LSL_Vector), BinOpStrFloatMulVec)); bos.Add ("vector/float", new BinOpStr (typeof (LSL_Vector), BinOpStrVecDivFloat, true)); bos.Add ("vector*integer", new BinOpStr (typeof (LSL_Vector), BinOpStrVecMulInt, true)); bos.Add ("integer*vector", new BinOpStr (typeof (LSL_Vector), BinOpStrIntMulVec)); bos.Add ("vector/integer", new BinOpStr (typeof (LSL_Vector), BinOpStrVecDivInt, true)); bos.Add ("vector*rotation", new BinOpStr (typeof (LSL_Vector), BinOpStrVecMulRot, true)); bos.Add ("vector/rotation", new BinOpStr (typeof (LSL_Vector), BinOpStrVecDivRot, true)); } /** * @brief These methods actually emit the code to perform the arithmetic. * @param scg = what script we are compiling * @param left = left-hand operand location in memory (type as given by BinOpStr entry) * @param right = right-hand operand location in memory (type as given by BinOpStr entry) * @param result = result location in memory (type as given by BinOpStr entry) */ private static void BinOpStrAndAnd (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeBool); right.PushVal (scg, errorAt, tokenTypeBool); scg.ilGen.Emit (errorAt, OpCodes.And); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrOrOr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeBool); right.PushVal (scg, errorAt, tokenTypeBool); scg.ilGen.Emit (errorAt, OpCodes.Or); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrBoolOrX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Or); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrBoolXorX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrBoolAndX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.And); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrBoolEqX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeBool); right.PushVal (scg, errorAt, tokenTypeBool); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrBoolNeX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeBool); right.PushVal (scg, errorAt, tokenTypeBool); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatEqX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatNeX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Ceq); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatLtX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Clt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatLeX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Cgt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatGtX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Cgt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatGeX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Clt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrFloatAddX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Add); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrFloatSubX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Sub); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrFloatMulX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Mul); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrFloatDivX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Div); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrFloatModX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Rem); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrXEqFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrXNeFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Ceq); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrXLtFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Clt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrXLeFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Cgt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrXGtFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Cgt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrXGeFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Clt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrXAddFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Add); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrXSubFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Sub); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrXMulFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Mul); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrXDivFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Div); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrXModFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Rem); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrCharEqChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrCharNeChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Ceq); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrCharLtChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Clt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrCharLeChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Cgt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrCharGtChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Cgt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrCharGeChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Clt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrCharAddInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Add); result.PopPost (scg, errorAt, tokenTypeChar); } private static void BinOpStrCharSubInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Sub); result.PopPost (scg, errorAt, tokenTypeChar); } private static void BinOpStrCharSubChar (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeChar); right.PushVal (scg, errorAt, tokenTypeChar); scg.ilGen.Emit (errorAt, OpCodes.Sub); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntEqInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrIntNeInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Ceq); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrIntLtInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Clt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrIntLeInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Cgt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrIntGtInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Cgt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrIntGeInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Clt); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrIntOrInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Or); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntXorInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntAndInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.And); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntAddInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Add); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntSubInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Sub); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntMulInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Mul); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntDivInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { // note that we must allow 0x800000/-1 -> 0x80000000 for lslangtest1.lsl // so sign-extend the operands to 64-bit then divide and truncate result result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Conv_I8); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Conv_I8); scg.ilGen.Emit (errorAt, OpCodes.Div); scg.ilGen.Emit (errorAt, OpCodes.Conv_I4); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntModInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { // note that we must allow 0x800000%-1 -> 0 for lslangtest1.lsl // so sign-extend the operands to 64-bit then mod and truncate result result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Conv_I8); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Conv_I8); scg.ilGen.Emit (errorAt, OpCodes.Rem); scg.ilGen.Emit (errorAt, OpCodes.Conv_I4); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntShlInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Shl); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrIntShrInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Shr); result.PopPost (scg, errorAt, tokenTypeInt); } private static void BinOpStrKeyEqX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_0); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrKeyNeX (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_0); scg.ilGen.Emit (errorAt, OpCodes.Ceq); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrListAddFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddFloat); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListAddInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddInt); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListAddKey (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddKey); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListAddRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddRot); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListAddStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddStr); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListAddVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListAddVec); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrFloatAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethFloatAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrIntAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethIntAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrKeyAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethKeyAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrRotAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrStrAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethStrAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrVecAddList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecAddList); result.PopPost (scg, errorAt, tokenTypeList); } private static void BinOpStrListEqList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListEqList); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrListNeList (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeList); right.PushVal (scg, errorAt, tokenTypeList); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethListNeList); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrRotEqRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotEqRot); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrRotNeRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotNeRot); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrRotAddRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotAddRot); result.PopPost (scg, errorAt, tokenTypeRot); } private static void BinOpStrRotSubRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotSubRot); result.PopPost (scg, errorAt, tokenTypeRot); } private static void BinOpStrRotMulRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotMulRot); result.PopPost (scg, errorAt, tokenTypeRot); } private static void BinOpStrRotDivRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeRot); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethRotDivRot); result.PopPost (scg, errorAt, tokenTypeRot); } private static void BinOpStrStrEqStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_0); scg.ilGen.Emit (errorAt, OpCodes.Ceq); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrStrNeStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_0); scg.ilGen.Emit (errorAt, OpCodes.Ceq); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Xor); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrStrLtStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_0); scg.ilGen.Emit (errorAt, OpCodes.Clt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrStrLeStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_1); scg.ilGen.Emit (errorAt, OpCodes.Clt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrStrGtStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_0); scg.ilGen.Emit (errorAt, OpCodes.Cgt); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrStrGeStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringCmpStringMethInfo); scg.ilGen.Emit (errorAt, OpCodes.Ldc_I4_M1); scg.ilGen.Emit (errorAt, OpCodes.Cgt); result.PopPost (scg, errorAt, tokenTypeBool); } // Called by many type combinations so both operands need to be cast to strings private static void BinOpStrStrAddStr (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeStr); right.PushVal (scg, errorAt, tokenTypeStr); scg.ilGen.Emit (errorAt, OpCodes.Call, stringAddStringMethInfo); result.PopPost (scg, errorAt, tokenTypeStr); } private static void BinOpStrVecEqVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecEqVec); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrVecNeVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecNeVec); result.PopPost (scg, errorAt, tokenTypeBool); } private static void BinOpStrVecAddVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecAddVec); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecSubVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecSubVec); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecMulVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecMulVec); result.PopPost (scg, errorAt, tokenTypeFloat); } private static void BinOpStrVecModVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecModVec); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecMulFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecMulFloat); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrFloatMulVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeFloat); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethFloatMulVec); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecDivFloat (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeFloat); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecDivFloat); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecMulInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecMulInt); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrIntMulVec (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeInt); right.PushVal (scg, errorAt, tokenTypeVec); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethIntMulVec); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecDivInt (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeInt); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecDivInt); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecMulRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecMulRot); result.PopPost (scg, errorAt, tokenTypeVec); } private static void BinOpStrVecDivRot (ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) { result.PopPre (scg, errorAt); left.PushVal (scg, errorAt, tokenTypeVec); right.PushVal (scg, errorAt, tokenTypeRot); scg.ilGen.Emit (errorAt, OpCodes.Call, infoMethVecDivRot); result.PopPost (scg, errorAt, tokenTypeVec); } /** * @brief These methods are called at runtime as helpers. * Needed to pick up functionality defined by overloaded operators of LSL_ types. * They need to be marked public or runtime says they are inaccessible. */ public static LSL_List MethListAddFloat (LSL_List left, double right) { return MethListAddObj (left, new LSL_Float (right)); } public static LSL_List MethListAddInt (LSL_List left, int right) { return MethListAddObj (left, new LSL_Integer (right)); } public static LSL_List MethListAddKey (LSL_List left, string right) { return MethListAddObj (left, new LSL_Key (right)); } public static LSL_List MethListAddRot (LSL_List left, LSL_Rotation right) { return MethListAddObj (left, right); } public static LSL_List MethListAddStr (LSL_List left, string right) { return MethListAddObj (left, new LSL_String (right)); } public static LSL_List MethListAddVec (LSL_List left, LSL_Vector right) { return MethListAddObj (left, right); } public static LSL_List MethListAddObj (LSL_List left, object right) { int oldlen = left.Length; object[] newarr = new object[oldlen+1]; Array.Copy (left.Data, newarr, oldlen); newarr[oldlen] = right; return new LSL_List (newarr); } public static LSL_List MethListAddList (LSL_List left, LSL_List right) { int leftlen = left.Length; int ritelen = right.Length; object[] newarr = new object[leftlen+ritelen]; Array.Copy (left.Data, newarr, leftlen); Array.Copy (right.Data, 0, newarr, leftlen, ritelen); return new LSL_List (newarr); } public static LSL_List MethFloatAddList (double left, LSL_List right) { return MethObjAddList (new LSL_Float (left), right); } public static LSL_List MethIntAddList (int left, LSL_List right) { return MethObjAddList (new LSL_Integer (left), right); } public static LSL_List MethKeyAddList (string left, LSL_List right) { return MethObjAddList (new LSL_Key (left), right); } public static LSL_List MethRotAddList (LSL_Rotation left, LSL_List right) { return MethObjAddList (left, right); } public static LSL_List MethStrAddList (string left, LSL_List right) { return MethObjAddList (new LSL_String (left), right); } public static LSL_List MethVecAddList (LSL_Vector left, LSL_List right) { return MethObjAddList (left, right); } public static LSL_List MethObjAddList (object left, LSL_List right) { int oldlen = right.Length; object[] newarr = new object[oldlen+1]; newarr[0] = left; Array.Copy (right.Data, 0, newarr, 1, oldlen); return new LSL_List (newarr); } public static bool MethListEqList (LSL_List left, LSL_List right) { return left == right; } // According to http://wiki.secondlife.com/wiki/LlGetListLength // jackassed LSL allows 'somelist != []' to get the length of a list public static int MethListNeList (LSL_List left, LSL_List right) { int leftlen = left.Length; int ritelen = right.Length; return leftlen - ritelen; } public static bool MethRotEqRot (LSL_Rotation left, LSL_Rotation right) { return left == right; } public static bool MethRotNeRot (LSL_Rotation left, LSL_Rotation right) { return left != right; } public static LSL_Rotation MethRotAddRot (LSL_Rotation left, LSL_Rotation right) { return left + right; } public static LSL_Rotation MethRotSubRot (LSL_Rotation left, LSL_Rotation right) { return left - right; } public static LSL_Rotation MethRotMulRot (LSL_Rotation left, LSL_Rotation right) { return left * right; } public static LSL_Rotation MethRotDivRot (LSL_Rotation left, LSL_Rotation right) { return left / right; } public static bool MethVecEqVec (LSL_Vector left, LSL_Vector right) { return left == right; } public static bool MethVecNeVec (LSL_Vector left, LSL_Vector right) { return left != right; } public static LSL_Vector MethVecAddVec (LSL_Vector left, LSL_Vector right) { return left + right; } public static LSL_Vector MethVecSubVec (LSL_Vector left, LSL_Vector right) { return left - right; } public static double MethVecMulVec (LSL_Vector left, LSL_Vector right) { return (double)(left * right).value; } public static LSL_Vector MethVecModVec (LSL_Vector left, LSL_Vector right) { return left % right; } public static LSL_Vector MethVecMulFloat (LSL_Vector left, double right) { return left * right; } public static LSL_Vector MethFloatMulVec (double left, LSL_Vector right) { return left * right; } public static LSL_Vector MethVecDivFloat (LSL_Vector left, double right) { return left / right; } public static LSL_Vector MethVecMulInt (LSL_Vector left, int right) { return left * right; } public static LSL_Vector MethIntMulVec (int left, LSL_Vector right) { return left * right; } public static LSL_Vector MethVecDivInt (LSL_Vector left, int right) { return left / right; } public static LSL_Vector MethVecMulRot (LSL_Vector left, LSL_Rotation right) { return left * right; } public static LSL_Vector MethVecDivRot (LSL_Vector left, LSL_Rotation right) { return left / right; } } }