IDynamic Search(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var regexpArg = args[0]; var regexpObj = regexpArg as NRegExp; if (regexpObj == null) { var constructor = (IConstructable)environment.RegExpConstructor; var pattern = regexpArg.ConvertToString(); regexpObj = (NRegExp)constructor.Construct(environment, environment.CreateArgs(new [] { pattern })); } var regExp = regexpObj.RegExpMatcher; var index = 0; do { var result = regExp(s, index); if (result.success) { return(environment.CreateNumber(index)); } } while (++index < s.Length); return(environment.CreateNumber(-1)); }
IDynamic ToLocaleUpperCase(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; return(environment.CreateString(s.ToUpper())); }
IDynamic LocaleCompare(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var that = args[0].ConvertToString().BaseValue; return(environment.CreateNumber((double)s.CompareTo(that))); }
IDynamic Trim(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; s = s.Trim(Machete.Compiler.CharSets.trimCharacters); return(environment.CreateString(s)); }
IDynamic LastIndexOf(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var searchString = args[0].ConvertToString().BaseValue; var position = args.Count > 1 ? (int)args[1].ConvertToInteger().BaseValue : int.MaxValue; var start = Math.Min(Math.Max(position, 0), s.Length); return(environment.CreateNumber((double)s.LastIndexOf(searchString, start))); }
IDynamic CharAt(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var position = (int)args[0].ConvertToInteger().BaseValue; if (position < 0 || position >= s.Length) { return(environment.CreateString(string.Empty)); } return(environment.CreateString(s.Substring(position, 1))); }
IDynamic CharCodeAt(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var position = (int)args[0].ConvertToInteger().BaseValue; if (position < 0 || position >= s.Length) { return(environment.CreateNumber(double.NaN)); } return(environment.CreateNumber((double)s[position])); }
IDynamic Concat(IEnvironment environment, IArgs args) { var sb = new StringBuilder(); { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); sb.Append(o.ConvertToString().BaseValue); foreach (var arg in args) { sb.Append(arg.ConvertToString().BaseValue); } } return(environment.CreateString(sb.ToString())); }
IDynamic Slice(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var start = args[0]; var end = args[1]; var intStart = (int)start.ConvertToInteger().BaseValue; var intEnd = end is IUndefined ? s.Length : (int)end.ConvertToInteger().BaseValue; var from = intStart < 0 ? Math.Max(s.Length + intStart, 0) : Math.Min(intStart, s.Length); var to = intStart < 0 ? Math.Max(s.Length + intEnd, 0) : Math.Min(intEnd, s.Length); var span = Math.Max(to - from, 0); return(environment.CreateString(s.Substring(from, span))); }
IDynamic Substring(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var start = args[0]; var end = args[1]; var startIndex = args[0].ConvertToInteger().BaseValue; var endIndex = end is IUndefined ? (double)s.Length : end.ConvertToInteger().BaseValue; var finalStart = Math.Min(Math.Max(startIndex, 0), s.Length); var finalEnd = Math.Min(Math.Max(endIndex, 0), s.Length); var from = (int)Math.Min(finalStart, finalEnd); var to = (int)Math.Max(finalStart, finalEnd); return(environment.CreateString(s.Substring(from, to - from))); }
IDynamic Substring(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var start = args[0]; var end = args[1]; var startIndex = args[0].ConvertToInteger().BaseValue; var endIndex = end is IUndefined ? (double)s.Length : end.ConvertToInteger().BaseValue; var finalStart = Math.Min(Math.Max(startIndex, 0), s.Length); var finalEnd = Math.Min(Math.Max(endIndex, 0), s.Length); var from = (int)Math.Min(finalStart, finalEnd); var to = (int)Math.Max(finalStart, finalEnd); return environment.CreateString(s.Substring(from, to - from)); }
IDynamic Split(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var separatorArg = args[0]; var limitArg = args[1]; var array = ((IConstructable)environment.ArrayConstructor).Construct(environment, environment.EmptyArgs); int limit = 0, lower = 0, upper = 0, count = 0; IPropertyDescriptor desc; IString value; // Using int32 instead of uint32 due to limitations of .NET arrays. limit = limitArg is IUndefined ? int.MaxValue : (int)limitArg.ConvertToUInt32().BaseValue; if (limit == 0) { return array; } var separatorObj = separatorArg as NRegExp; if (separatorObj != null) { do { var result = separatorObj.RegExpMatcher(s, upper); if (!result.success) { upper++; } else { upper = result.matchState.endIndex; value = environment.CreateString(s.Substring(lower, upper - lower - 1)); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(count.ToString(), desc, true); if (++count == limit) return array; var captures = result.matchState.captures; for (int i = 0; i < captures.Length; i++) { value = environment.CreateString(captures[i]); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(count.ToString(), desc, true); if (++count == limit) return array; } lower = upper; } } while (upper < s.Length); value = environment.CreateString(s.Substring(lower)); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(count.ToString(), desc, true); } else { var separatorStr = ((IString)separatorArg).BaseValue; var pieces = s.Split(new[] { separatorStr }, StringSplitOptions.None); for (int i = 0; i < pieces.Length; i++) { value = environment.CreateString(pieces[i]); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(i.ToString(), desc, true); if (++count == limit) return array; } } return array; }
IDynamic Slice(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var start = args[0]; var end = args[1]; var intStart = (int)start.ConvertToInteger().BaseValue; var intEnd = end is IUndefined ? s.Length : (int)end.ConvertToInteger().BaseValue; var from = intStart < 0 ? Math.Max(s.Length + intStart, 0) : Math.Min(intStart, s.Length); var to = intStart < 0 ? Math.Max(s.Length + intEnd, 0) : Math.Min(intEnd, s.Length); var span = Math.Max(to - from, 0); return environment.CreateString(s.Substring(from, span)); }
IDynamic Search(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var regexpArg = args[0]; var regexpObj = regexpArg as NRegExp; if (regexpObj == null) { var constructor = (IConstructable)environment.RegExpConstructor; var pattern = regexpArg.ConvertToString(); regexpObj = (NRegExp)constructor.Construct(environment, environment.CreateArgs(new [] { pattern })); } var regExp = regexpObj.RegExpMatcher; var index = 0; do { var result = regExp(s, index); if (result.success) { return environment.CreateNumber(index); } } while (++index < s.Length); return environment.CreateNumber(-1); }
IDynamic Match(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var dynS = o.ConvertToString(); var s = dynS.BaseValue; var regexpArg = args[0]; var regexpObj = regexpArg as NRegExp; if (regexpObj == null) { var constructor = (IConstructable)environment.RegExpConstructor; var pattern = regexpArg.ConvertToString(); regexpObj = (NRegExp)constructor.Construct(environment, environment.CreateArgs(new [] { pattern })); } var exec = ((ICallable)regexpObj.Get("exec")); var execArgs = environment.CreateArgs(new [] { dynS }); if (!regexpObj.Get("global").ConvertToBoolean().BaseValue) { return exec.Call(environment, regexpObj, execArgs); } else { var constructor = (IConstructable)environment.ArrayConstructor; var array = constructor.Construct(environment, environment.EmptyArgs); var previousLastIndex = 0; var lastMatch = true; var n = 0; while (lastMatch) { var result = exec.Call(environment, regexpObj, execArgs); switch (result.TypeCode) { case LanguageTypeCode.Null: lastMatch = false; break; default: var thisIndex = (int)regexpObj.Get("lastIndex").ConvertToNumber().BaseValue; if (thisIndex == previousLastIndex) { thisIndex += 1; regexpObj.Put("lastIndex", environment.CreateNumber(thisIndex), false); previousLastIndex = thisIndex; } else { previousLastIndex = thisIndex; } var matchStr = ((IObject)result).Get("0"); var desc = environment.CreateDataDescriptor(matchStr, true, true, true); array.DefineOwnProperty(n.ToString(), desc, true); n++; break; } } if (n == 0) { return environment.Null; } return array; } }
IDynamic LocaleCompare(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var that = args[0].ConvertToString().BaseValue; return environment.CreateNumber((double)s.CompareTo(that)); }
IDynamic LastIndexOf(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var searchString = args[0].ConvertToString().BaseValue; var position = args.Count > 1 ? (int)args[1].ConvertToInteger().BaseValue : int.MaxValue; var start = Math.Min(Math.Max(position, 0), s.Length); return environment.CreateNumber((double)s.LastIndexOf(searchString, start)); }
IDynamic Concat(IEnvironment environment, IArgs args) { var sb = new StringBuilder(); { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); sb.Append(o.ConvertToString().BaseValue); foreach (var arg in args) { sb.Append(arg.ConvertToString().BaseValue); } } return environment.CreateString(sb.ToString()); }
IDynamic CharCodeAt(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var position = (int)args[0].ConvertToInteger().BaseValue; if (position < 0 || position >= s.Length) { return environment.CreateNumber(double.NaN); } return environment.CreateNumber((double)s[position]); }
IDynamic ToUpperCase(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; return environment.CreateString(s.ToUpperInvariant()); }
IDynamic Split(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var separatorArg = args[0]; var limitArg = args[1]; var array = ((IConstructable)environment.ArrayConstructor).Construct(environment, environment.EmptyArgs); int limit = 0, lower = 0, upper = 0, count = 0; IPropertyDescriptor desc; IString value; // Using int32 instead of uint32 due to limitations of .NET arrays. limit = limitArg is IUndefined ? int.MaxValue : (int)limitArg.ConvertToUInt32().BaseValue; if (limit == 0) { return(array); } var separatorObj = separatorArg as NRegExp; if (separatorObj != null) { do { var result = separatorObj.RegExpMatcher(s, upper); if (!result.success) { upper++; } else { upper = result.matchState.endIndex; value = environment.CreateString(s.Substring(lower, upper - lower - 1)); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(count.ToString(), desc, true); if (++count == limit) { return(array); } var captures = result.matchState.captures; for (int i = 0; i < captures.Length; i++) { value = environment.CreateString(captures[i]); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(count.ToString(), desc, true); if (++count == limit) { return(array); } } lower = upper; } } while (upper < s.Length); value = environment.CreateString(s.Substring(lower)); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(count.ToString(), desc, true); } else { var separatorStr = ((IString)separatorArg).BaseValue; var pieces = s.Split(new[] { separatorStr }, StringSplitOptions.None); for (int i = 0; i < pieces.Length; i++) { value = environment.CreateString(pieces[i]); desc = environment.CreateDataDescriptor(value, true, true, true); array.DefineOwnProperty(i.ToString(), desc, true); if (++count == limit) { return(array); } } } return(array); }
IDynamic Match(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var dynS = o.ConvertToString(); var s = dynS.BaseValue; var regexpArg = args[0]; var regexpObj = regexpArg as NRegExp; if (regexpObj == null) { var constructor = (IConstructable)environment.RegExpConstructor; var pattern = regexpArg.ConvertToString(); regexpObj = (NRegExp)constructor.Construct(environment, environment.CreateArgs(new [] { pattern })); } var exec = ((ICallable)regexpObj.Get("exec")); var execArgs = environment.CreateArgs(new [] { dynS }); if (!regexpObj.Get("global").ConvertToBoolean().BaseValue) { return(exec.Call(environment, regexpObj, execArgs)); } else { var constructor = (IConstructable)environment.ArrayConstructor; var array = constructor.Construct(environment, environment.EmptyArgs); var previousLastIndex = 0; var lastMatch = true; var n = 0; while (lastMatch) { var result = exec.Call(environment, regexpObj, execArgs); switch (result.TypeCode) { case LanguageTypeCode.Null: lastMatch = false; break; default: var thisIndex = (int)regexpObj.Get("lastIndex").ConvertToNumber().BaseValue; if (thisIndex == previousLastIndex) { thisIndex += 1; regexpObj.Put("lastIndex", environment.CreateNumber(thisIndex), false); previousLastIndex = thisIndex; } else { previousLastIndex = thisIndex; } var matchStr = ((IObject)result).Get("0"); var desc = environment.CreateDataDescriptor(matchStr, true, true, true); array.DefineOwnProperty(n.ToString(), desc, true); n++; break; } } if (n == 0) { return(environment.Null); } return(array); } }
IDynamic Trim(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; s = s.Trim(Machete.Compiler.CharSets.trimCharacters); return environment.CreateString(s); }
IDynamic CharAt(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding; environment.CheckObjectCoercible(o); var s = o.ConvertToString().BaseValue; var position = (int)args[0].ConvertToInteger().BaseValue; if (position < 0 || position >= s.Length) { return environment.CreateString(string.Empty); } return environment.CreateString(s.Substring(position, 1)); }