OpenSimMirror/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptBinOpStr.cs

1560 lines
77 KiB
C#

/*
* 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<string, BinOpStr> defined = DefineBinOps ();
public Type outtype; // type of result of computation
public BinOpStrEmitBO emitBO; // how to compute result
public bool rmwOK; // is the <operator>= 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 <lefttype><opcode><righttype>,
* where <lefttype> and <righttype> are strings returned by (TokenType...).ToString()
* and <opcode> 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<string, BinOpStr> DefineBinOps ()
{
Dictionary<string, BinOpStr> bos = new Dictionary<string, BinOpStr> ();
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<string, BinOpStr> bos2 = new Dictionary<string, BinOpStr> ();
foreach (KeyValuePair<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> 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), BinOpStrXLtFloat));
bos.Add (x + "<=float", new BinOpStr (typeof (bool), BinOpStrXLeFloat));
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<string, BinOpStr> bos)
{
bos.Add ("char==char", new BinOpStr (typeof (bool), BinOpStrCharEqChar));
bos.Add ("char!=char", new BinOpStr (typeof (bool), BinOpStrCharNeChar));
bos.Add ("char<char", new BinOpStr (typeof (bool), BinOpStrCharLtChar));
bos.Add ("char<=char", new BinOpStr (typeof (bool), BinOpStrCharLeChar));
bos.Add ("char>char", 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<string, BinOpStr> bos)
{
bos.Add ("integer==integer", new BinOpStr (typeof (bool), BinOpStrIntEqInt));
bos.Add ("integer!=integer", new BinOpStr (typeof (bool), BinOpStrIntNeInt));
bos.Add ("integer<integer", new BinOpStr (typeof (bool), BinOpStrIntLtInt));
bos.Add ("integer<=integer", new BinOpStr (typeof (bool), BinOpStrIntLeInt));
bos.Add ("integer>integer", 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), BinOpStrIntShlInt, true));
bos.Add ("integer>>integer", new BinOpStr (typeof (int), BinOpStrIntShrInt, true));
}
private static void DefineBinOpsKeyX (Dictionary<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> 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<string, BinOpStr> bos)
{
bos.Add ("string==string", new BinOpStr (typeof (bool), BinOpStrStrEqStr));
bos.Add ("string!=string", new BinOpStr (typeof (bool), BinOpStrStrNeStr));
bos.Add ("string<string", new BinOpStr (typeof (bool), BinOpStrStrLtStr));
bos.Add ("string<=string", new BinOpStr (typeof (bool), BinOpStrStrLeStr));
bos.Add ("string>string", 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<string, BinOpStr> 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;
}
}
}