public static DekiScriptLiteral IdentityNotEqual(DekiScriptLiteral left, DekiScriptLiteral right) { if (left.ScriptType == right.ScriptType) { switch (left.ScriptType) { case DekiScriptType.NIL: return(DekiScriptBool.False); case DekiScriptType.BOOL: return(Constant(left.AsBool() != right.AsBool())); case DekiScriptType.NUM: return(Constant(left.AsNumber() != right.AsNumber())); case DekiScriptType.STR: return(Constant(!StringUtil.EqualsInvariant(left.AsString(), right.AsString()))); default: return(Constant(!ReferenceEquals(left, right))); } } return(DekiScriptBool.True); }
public static DekiScriptLiteral NotEqual(DekiScriptLiteral left, DekiScriptLiteral right) { if (DekiScriptLiteral.CoerceValuesToSameType(ref left, ref right)) { switch (left.ScriptType) { case DekiScriptType.NIL: return(DekiScriptBool.False); case DekiScriptType.BOOL: return(Constant(left.AsBool() != right.AsBool())); case DekiScriptType.NUM: return(Constant(left.AsNumber() != right.AsNumber())); case DekiScriptType.STR: return(Constant(!StringUtil.EqualsInvariant(left.AsString(), right.AsString()))); default: return(Constant(!object.ReferenceEquals(left, right))); } } return(DekiScriptBool.True); }
public static bool CoerceValuesToSameType(ref DekiScriptLiteral left, ref DekiScriptLiteral right) { // weed out the trivial case where the literals cannot be converted switch(left.ScriptType) { case DekiScriptType.NIL: case DekiScriptType.URI: case DekiScriptType.LIST: case DekiScriptType.MAP: case DekiScriptType.XML: // we can't convert complex literals; only succeed if the types match return left.ScriptType == right.ScriptType; } switch(right.ScriptType) { case DekiScriptType.NIL: case DekiScriptType.URI: case DekiScriptType.LIST: case DekiScriptType.MAP: case DekiScriptType.XML: // we can't convert complex literals; only succeed if the types match return left.ScriptType == right.ScriptType; } // now determine what needs to be converted switch(left.ScriptType) { case DekiScriptType.BOOL: switch(right.ScriptType) { case DekiScriptType.BOOL: // nothing to do return true; case DekiScriptType.NUM: // convert left value from bool to number left = Constant(left.AsNumber()); return true; case DekiScriptType.STR: { // check if right string can be converted to bool; otherwise convert left bool to string bool? value = right.AsBool(); if(value == null) { left = Constant(left.AsString()); } else { right = Constant(value); } return true; } } break; case DekiScriptType.NUM: switch(right.ScriptType) { case DekiScriptType.BOOL: // convert right value from bool to number right = Constant(right.AsNumber()); return true; case DekiScriptType.NUM: // nothing to do return true; case DekiScriptType.STR: { // check if right string can be converted to number; otherwise convert left number to string double? value = right.AsNumber(); if(value == null) { left = Constant(left.AsString()); } else { right = Constant(value); } return true; } } break; case DekiScriptType.STR: switch(right.ScriptType) { case DekiScriptType.BOOL: { // check if left string can be converted to bool; otherwise convert right bool to string bool? value = left.AsBool(); if(value == null) { right = Constant(right.AsString()); } else { left = Constant(value); } return true; } case DekiScriptType.NUM: { // check if left string can be converted to number; otherwise convert right number to string double? value = left.AsNumber(); if(value == null) { right = Constant(right.AsString()); } else { left = Constant(value); } return true; } case DekiScriptType.STR: // nothing to do return true; } break; } throw new InvalidOperationException(string.Format("invalid value pair: left = {0}, right = {1}", left.ScriptTypeName, right.ScriptTypeName)); }
internal void InsertValueBeforeNode(XmlNode parent, XmlNode reference, DekiScriptLiteral value) { if((value is DekiScriptXml) || (value is DekiScriptUri)) { XDoc xml = value.AsEmbeddableXml(Mode == DekiScriptEvalMode.EvaluateSafeMode); if(xml.HasName("html")) { // TODO (steveb): merge XML namespaces // merge <head> and <tail> sections AddHeadElements(xml); AddTailElements(xml); // loop over body elements in response foreach(XDoc body in xml["body"]) { string target = body["@target"].AsText; string conflict = body["@conflict"].AsText ?? "ignore"; // check if the main body is targeted or something else if(string.IsNullOrEmpty(target)) { // append body nodes foreach(XmlNode node in body.AsXmlNode.ChildNodes) { parent.InsertBefore(parent.OwnerDocument.ImportNode(node, true), reference); } } else { // check if the targeted body already exists if(Bodies.ContainsKey(target) && !StringUtil.EqualsInvariant(conflict, "replace")) { if(StringUtil.EqualsInvariant(conflict, "append")) { // append nodes to existing body Bodies[target].Add(body.AsXmlNode); } } else { // create a new body element List<XmlNode> list = new List<XmlNode>(); list.Add(body.AsXmlNode); Bodies[target] = list; } } } } else if(!xml.IsEmpty) { // replace the current node with the entire document parent.InsertBefore(parent.OwnerDocument.ImportNode(xml.AsXmlNode, true), reference); } } else if(value is DekiScriptComplexLiteral) { // append text respresentation of value parent.InsertBefore(CreateTextNode(value.ToString()), reference); } else { // append value cast to text string text = value.AsString(); if(!string.IsNullOrEmpty(text)) { parent.InsertBefore(CreateTextNode(text), reference); } } }
public static bool CoerceValuesToSameType(ref DekiScriptLiteral left, ref DekiScriptLiteral right) { // weed out the trivial case where the literals cannot be converted switch (left.ScriptType) { case DekiScriptType.NIL: case DekiScriptType.URI: case DekiScriptType.LIST: case DekiScriptType.MAP: case DekiScriptType.XML: // we can't convert complex literals; only succeed if the types match return(left.ScriptType == right.ScriptType); } switch (right.ScriptType) { case DekiScriptType.NIL: case DekiScriptType.URI: case DekiScriptType.LIST: case DekiScriptType.MAP: case DekiScriptType.XML: // we can't convert complex literals; only succeed if the types match return(left.ScriptType == right.ScriptType); } // now determine what needs to be converted switch (left.ScriptType) { case DekiScriptType.BOOL: switch (right.ScriptType) { case DekiScriptType.BOOL: // nothing to do return(true); case DekiScriptType.NUM: // convert left value from bool to number left = Constant(left.AsNumber()); return(true); case DekiScriptType.STR: { // check if right string can be converted to bool; otherwise convert left bool to string bool?value = right.AsBool(); if (value == null) { left = Constant(left.AsString()); } else { right = Constant(value); } return(true); } } break; case DekiScriptType.NUM: switch (right.ScriptType) { case DekiScriptType.BOOL: // convert right value from bool to number right = Constant(right.AsNumber()); return(true); case DekiScriptType.NUM: // nothing to do return(true); case DekiScriptType.STR: { // check if right string can be converted to number; otherwise convert left number to string double?value = right.AsNumber(); if (value == null) { left = Constant(left.AsString()); } else { right = Constant(value); } return(true); } } break; case DekiScriptType.STR: switch (right.ScriptType) { case DekiScriptType.BOOL: { // check if left string can be converted to bool; otherwise convert right bool to string bool?value = left.AsBool(); if (value == null) { right = Constant(right.AsString()); } else { left = Constant(value); } return(true); } case DekiScriptType.NUM: { // check if left string can be converted to number; otherwise convert right number to string double?value = left.AsNumber(); if (value == null) { right = Constant(right.AsString()); } else { left = Constant(value); } return(true); } case DekiScriptType.STR: // nothing to do return(true); } break; } throw new InvalidOperationException(string.Format("invalid value pair: left = {0}, right = {1}", left.ScriptTypeName, right.ScriptTypeName)); }