private static IDynamic ForEach(IEnvironment environment, IArgs args) { var obj = environment.Context.ThisBinding.ConvertToObject(); var callArgs = new IDynamic[] { null, null, obj }; var length = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; var thisArg = args[1]; if (callbackfn == null) { throw environment.CreateTypeError("The first parameter 'callbackfn' must be callable."); } for (uint i = 0; i < length; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { callArgs[0] = obj.Get(key); callArgs[1] = environment.CreateNumber(i); callbackfn.Call(environment, thisArg, environment.CreateArgs(callArgs)); } } return(environment.Undefined); }
private static IDynamic Map(IEnvironment environment, IArgs args) { var result = ((IConstructable)environment.ArrayConstructor).Construct(environment, environment.EmptyArgs); var obj = environment.Context.ThisBinding.ConvertToObject(); var callArgs = new IDynamic[] { null, null, obj }; var length = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; var thisArg = args[1]; if (callbackfn == null) { throw environment.CreateTypeError("The first parameter 'callbackfn' must be callable."); } for (uint i = 0; i < length; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { callArgs[0] = obj.Get(key); callArgs[1] = environment.CreateNumber(i); var value = callbackfn.Call(environment, thisArg, environment.CreateArgs(callArgs)); result.DefineOwnProperty(key, environment.CreateDataDescriptor(value, true, true, true), false); } } return(result); }
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)); }
private static IDynamic Filter(IEnvironment environment, IArgs args) { var result = ((IConstructable)environment.ArrayConstructor).Construct(environment, environment.EmptyArgs); var obj = environment.Context.ThisBinding.ConvertToObject(); var length = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; var thisArg = args[1]; if (callbackfn == null) { throw environment.CreateTypeError(""); } for (uint i = 0; i < length; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { var value = obj.Get(key); var callArgs = environment.CreateArgs(new[] { value, environment.CreateNumber(i), obj }); var include = callbackfn.Call(environment, thisArg, callArgs); if (include.ConvertToBoolean().BaseValue) { result.DefineOwnProperty(key, environment.CreateDataDescriptor(value, true, true, true), false); } } } return(result); }
internal static IDynamic Now(IEnvironment environment, IArgs args) { var value = environment.CreateNumber((DateTime.UtcNow - _utcStart).TotalMilliseconds); var constructArgs = environment.CreateArgs(new IDynamic[] { value }); return(((IConstructable)environment.DateConstructor).Construct(environment, constructArgs)); }
private static IDynamic ReduceRight(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding.ConvertToObject(); var len = (uint)o.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; if (callbackfn == null) { throw environment.CreateTypeError(""); } if (len == 0 && args.Count < 2) { throw environment.CreateTypeError(""); } uint k = len - 1; var accumulator = args[1]; if (args.Count < 2) { var found = false; for (;; k--) { var key = k.ToString(); if (o.HasProperty(key)) { found = true; accumulator = o.Get(key); k--; break; } if (k == 0) { break; } } if (!found) { throw environment.CreateTypeError(""); } } for (;; k--) { var key = k.ToString(); if (o.HasProperty(key)) { var callArgs = environment.CreateArgs(new[] { accumulator, o.Get(key), environment.CreateNumber(k), o }); accumulator = callbackfn.Call(environment, environment.Undefined, callArgs); } if (k == 0) { break; } } return(accumulator); }
internal static IDynamic Iterate(IEnvironment environment, IArgs args) { var iterator = new Iterator(environment, args[1]); var callback = args[0] as ICallable; if (callback == null) throw environment.CreateTypeError("The argument 'callback' must be a callable function."); while (iterator.Next()) { var callArgs = environment.CreateArgs(new[] { iterator.Current }); callback.Call(environment, environment.Undefined, callArgs); } return environment.Undefined; }
public override IDynamic Next(IEnvironment environment, IArgs args) { if (_complete) return environment.False; _initialized = true; while (_iterator.Next()) { var callArgs = environment.CreateArgs(new[] { _iterator.Current }); _current = _mapping.Call(environment, environment.Undefined, callArgs); return environment.True; } _complete = true; return environment.False; }
public override IDynamic Next(IEnvironment environment, IArgs args) { if (_complete) return environment.False; _initialized = true; while (_iterator.Next()) { var callArgs = environment.CreateArgs(new[] { _iterator.Current }); if (_predicate.Call(environment, environment.Undefined, callArgs).ConvertToBoolean().BaseValue) return environment.True; } _complete = true; return environment.False; }
internal static IDynamic Iterate(IEnvironment environment, IArgs args) { var iterator = new Iterator(environment, args[1]); var callback = args[0] as ICallable; if (callback == null) { throw environment.CreateTypeError("The argument 'callback' must be a callable function."); } while (iterator.Next()) { var callArgs = environment.CreateArgs(new[] { iterator.Current }); callback.Call(environment, environment.Undefined, callArgs); } return(environment.Undefined); }
public override IDynamic Next(IEnvironment environment, IArgs args) { if (_complete) { return(environment.False); } _initialized = true; while (_iterator.Next()) { var callArgs = environment.CreateArgs(new[] { _iterator.Current }); _current = _mapping.Call(environment, environment.Undefined, callArgs); return(environment.True); } _complete = true; return(environment.False); }
private static IDynamic Call(IEnvironment environment, IArgs args) { var callable = environment.Context.ThisBinding as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var thisArg = args[0]; var callArgs = environment.EmptyArgs; if (args.Count > 1) { callArgs = environment.CreateArgs(args.Skip(1)); } return(callable.Call(environment, thisArg, callArgs)); }
private static IDynamic Apply(IEnvironment environment, IArgs args) { var callable = environment.Context.ThisBinding as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var thisArg = args[0]; var argArray = args[1]; switch (argArray.TypeCode) { case LanguageTypeCode.Undefined: case LanguageTypeCode.Null: return(callable.Call(environment, thisArg, environment.EmptyArgs)); case LanguageTypeCode.Object: break; default: throw environment.CreateTypeError(""); } var argList = new List <IDynamic>(); var argArrayObj = argArray.ConvertToObject(); var len = argArrayObj.Get("length"); switch (len.TypeCode) { case LanguageTypeCode.Undefined: case LanguageTypeCode.Null: throw environment.CreateTypeError(""); } var n = (uint)len.ConvertToUInt32().BaseValue; var index = (uint)0; while (index < n) { argList.Add(argArrayObj.Get(index.ToString())); index++; } var callArgs = environment.CreateArgs(argList); return(callable.Call(environment, thisArg, callArgs)); }
public override IDynamic Next(IEnvironment environment, IArgs args) { if (_complete) { return(environment.False); } _initialized = true; while (_iterator.Next()) { var callArgs = environment.CreateArgs(new[] { _iterator.Current }); if (_predicate.Call(environment, environment.Undefined, callArgs).ConvertToBoolean().BaseValue) { return(environment.True); } } _complete = true; return(environment.False); }
private static IDynamic Bind(IEnvironment environment, IArgs args) { var callable = environment.Context.ThisBinding as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var target = (IObject)callable; var thisArg = args[0]; var callArgs = environment.EmptyArgs; var func = new NBoundFunction(environment); if (args.Count > 1) { callArgs = environment.CreateArgs(args.Skip(1)); } func.Class = "Function"; func.Extensible = true; func.Prototype = environment.FunctionPrototype; func.TargetFunction = target; func.BoundThis = thisArg; func.BoundArguments = callArgs; var length = 0.0; if (target.Class == "Function") { length = callArgs.Count - target.Get("length").ConvertToUInt32().BaseValue; } var lengthNum = environment.CreateNumber(length); var thrower = environment.ThrowTypeErrorFunction; var desc = environment.CreateDataDescriptor(lengthNum, false, false, false); func.DefineOwnProperty("length", desc, false); desc = environment.CreateAccessorDescriptor(thrower, thrower, false, false); func.DefineOwnProperty("caller", desc, false); func.DefineOwnProperty("arguments", desc, false); return(func); }
internal static IDynamic Create(IEnvironment environment, IArgs args) { if (args[0].TypeCode != LanguageTypeCode.Object) { throw environment.CreateTypeError(""); } var obj = args[0].ConvertToObject(); var newObj = environment.CreateObject(); newObj.Prototype = obj; if (args.Count > 1) { var props = args[1]; if (props.TypeCode != LanguageTypeCode.Undefined) { return DefineProperties(environment, environment.CreateArgs(new [] { newObj, props })); } } return newObj; }
internal static IDynamic Create(IEnvironment environment, IArgs args) { if (args[0].TypeCode != LanguageTypeCode.Object) { throw environment.CreateTypeError(""); } var obj = args[0].ConvertToObject(); var newObj = environment.CreateObject(); newObj.Prototype = obj; if (args.Count > 1) { var props = args[1]; if (props.TypeCode != LanguageTypeCode.Undefined) { return(DefineProperties(environment, environment.CreateArgs(new [] { newObj, props }))); } } return(newObj); }
IDynamic Replace(IEnvironment environment, IArgs args) { var so = environment.Context.ThisBinding.ConvertToString(); var s = so.BaseValue; var sb = new StringBuilder(); var searchValueArg = args[0]; var replaceValueArg = args[1]; var replaceValueFunc = replaceValueArg as ICallable; var replaceValueString = replaceValueArg.ConvertToString(); var matchSubstring = ""; var i = 0; if (searchValueArg is NRegExp) { var regExpObj = (NRegExp)searchValueArg; var matcher = regExpObj.RegExpMatcher; Func<int, RegExpParser.MatchState, Func<string, string>> makeReplacer = null; if (replaceValueFunc != null) { makeReplacer = (startIndex, state) => v => { var cArgs = new List<IDynamic>(); cArgs.Add(environment.CreateString(v)); foreach (var c in state.captures) cArgs.Add(c == null ? (IDynamic)environment.Null : environment.CreateString(c)); cArgs.Add(environment.CreateNumber(startIndex)); cArgs.Add(so); var result = replaceValueFunc.Call( environment, environment.Undefined, environment.CreateArgs(cArgs) ); return result.ConvertToString().BaseValue; }; } else { var replacer = MakeReplacer(replaceValueString.BaseValue); makeReplacer = (_, state) => v => replacer(v, state); } var global = regExpObj.Flags.Contains("g"); i = global ? (int)regExpObj.Get("lastIndex").ConvertToNumber().BaseValue : 0; do { var r = matcher(s, i); if (!r.success) { sb.Append(s[i++]); continue; } matchSubstring = s.Substring(i, r.matchState.endIndex - i); sb.Append(makeReplacer(i, r.matchState)(matchSubstring)); if (!global) break; i = r.matchState.endIndex; regExpObj.Put("lastIndex", environment.CreateNumber(i), false); } while (i < s.Length); } else { Func<string, string> replace = null; if (replaceValueFunc == null) { replace = v => replaceValueString.BaseValue; } else { replace = v => replaceValueFunc.Call( environment, environment.Undefined, environment.CreateArgs( new[] { environment.CreateString(v) } ) ) .ConvertToString() .BaseValue; } var searchValue = args[0].ConvertToString().BaseValue; var index = 0; do { var resultIndex = s.IndexOf(searchValue, index); if (resultIndex < 0) { sb.Append(s.Substring(index)); break; } matchSubstring = s.Substring(resultIndex, searchValue.Length); sb.Append(replace(matchSubstring)); index = resultIndex + searchValue.Length; } while (index < s.Length); } return environment.CreateString(sb.ToString()); }
private static IDynamic Sort(IEnvironment environment, IArgs args) { var obj = environment.Context.ThisBinding.ConvertToObject(); var len = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var comparefn = args[0]; var sortCompare = new Func <uint, uint, IDynamic>((j, k) => { var jString = j.ToString(); var kString = k.ToString(); var hasJ = obj.HasProperty(jString); var hasK = obj.HasProperty(kString); if (!hasJ || !hasK) { if (!hasJ && !hasK) { return(environment.CreateNumber(0)); } else if (!hasJ) { return(environment.CreateNumber(1)); } else { return(environment.CreateNumber(-1)); } } var x = obj.Get(jString); var y = obj.Get(kString); if (x is IUndefined || y is IUndefined) { if (x is IUndefined && y is IUndefined) { return(environment.CreateNumber(0)); } else if (x is IUndefined) { return(environment.CreateNumber(1)); } else { return(environment.CreateNumber(-1)); } } if (comparefn.TypeCode != LanguageTypeCode.Undefined) { var callable = comparefn as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } return(callable.Call(environment, environment.Undefined, environment.CreateArgs(new[] { x, y }))); } var xString = x.ConvertToString(); var yString = y.ConvertToString(); var xLess = xString.Op_Lessthan(yString); if (((IBoolean)xLess).BaseValue) { return(environment.CreateNumber(-1)); } var yLess = yString.Op_Lessthan(xString); if (((IBoolean)yLess).BaseValue) { return(environment.CreateNumber(1)); } return(environment.CreateNumber(0)); }); var items = new List <IDynamic>(); for (uint i = 0; i < len; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { var value = obj.Get(key); items.Add(value); obj.Delete(key, true); } } items.Sort((x, y) => { if (x is IUndefined || y is IUndefined) { if (x is IUndefined && y is IUndefined) { return(0); } else if (x is IUndefined) { return(1); } else { return(-1); } } if (comparefn.TypeCode != LanguageTypeCode.Undefined) { var callable = comparefn as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var result = callable.Call(environment, environment.Undefined, environment.CreateArgs(new[] { x, y })); var number = result.ConvertToInteger(); if (double.IsNaN(number.BaseValue) || double.IsInfinity(number.BaseValue)) { return(0); } return((int)number.BaseValue); } var xString = x.ConvertToString(); var yString = y.ConvertToString(); var xLess = xString.Op_Lessthan(yString); if (((IBoolean)xLess).BaseValue) { return(-1); } var yLess = yString.Op_Lessthan(xString); if (((IBoolean)yLess).BaseValue) { return(1); } return(0); }); for (int i = 0; i < items.Count; i++) { var key = i.ToString(); obj.Put(key, items[i], true); } return(obj); }
private static IDynamic Apply(IEnvironment environment, IArgs args) { var callable = environment.Context.ThisBinding as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var thisArg = args[0]; var argArray = args[1]; switch (argArray.TypeCode) { case LanguageTypeCode.Undefined: case LanguageTypeCode.Null: return callable.Call(environment, thisArg, environment.EmptyArgs); case LanguageTypeCode.Object: break; default: throw environment.CreateTypeError(""); } var argList = new List<IDynamic>(); var argArrayObj = argArray.ConvertToObject(); var len = argArrayObj.Get("length"); switch (len.TypeCode) { case LanguageTypeCode.Undefined: case LanguageTypeCode.Null: throw environment.CreateTypeError(""); } var n = (uint)len.ConvertToUInt32().BaseValue; var index = (uint)0; while (index < n) { argList.Add(argArrayObj.Get(index.ToString())); index++; } var callArgs = environment.CreateArgs(argList); return callable.Call(environment, thisArg, callArgs); }
private static IDynamic Bind(IEnvironment environment, IArgs args) { var callable = environment.Context.ThisBinding as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var target = (IObject)callable; var thisArg = args[0]; var callArgs = environment.EmptyArgs; var func = new NBoundFunction(environment); if (args.Count > 1) { callArgs = environment.CreateArgs(args.Skip(1)); } func.Class = "Function"; func.Extensible = true; func.Prototype = environment.FunctionPrototype; func.TargetFunction = target; func.BoundThis = thisArg; func.BoundArguments = callArgs; var length = 0.0; if (target.Class == "Function") { length = callArgs.Count - target.Get("length").ConvertToUInt32().BaseValue; } var lengthNum = environment.CreateNumber(length); var thrower = environment.ThrowTypeErrorFunction; var desc = environment.CreateDataDescriptor(lengthNum, false, false, false); func.DefineOwnProperty("length", desc, false); desc = environment.CreateAccessorDescriptor(thrower, thrower, false, false); func.DefineOwnProperty("caller", desc, false); func.DefineOwnProperty("arguments", desc, false); return func; }
private static IDynamic ReduceRight(IEnvironment environment, IArgs args) { var o = environment.Context.ThisBinding.ConvertToObject(); var len = (uint)o.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; if (callbackfn == null) throw environment.CreateTypeError(""); if (len == 0 && args.Count < 2) throw environment.CreateTypeError(""); uint k = len - 1; var accumulator = args[1]; if (args.Count < 2) { var found = false; for (;; k--) { var key = k.ToString(); if (o.HasProperty(key)) { found = true; accumulator = o.Get(key); k--; break; } if (k == 0) break; } if (!found) throw environment.CreateTypeError(""); } for (;; k--) { var key = k.ToString(); if (o.HasProperty(key)) { var callArgs = environment.CreateArgs(new[] { accumulator, o.Get(key), environment.CreateNumber(k), o }); accumulator = callbackfn.Call(environment, environment.Undefined, callArgs); } if (k == 0) break; } return accumulator; }
private static IDynamic Map(IEnvironment environment, IArgs args) { var result = ((IConstructable)environment.ArrayConstructor).Construct(environment, environment.EmptyArgs); var obj = environment.Context.ThisBinding.ConvertToObject(); var callArgs = new IDynamic[] { null, null, obj }; var length = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; var thisArg = args[1]; if (callbackfn == null) { throw environment.CreateTypeError("The first parameter 'callbackfn' must be callable."); } for (uint i = 0; i < length; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { callArgs[0] = obj.Get(key); callArgs[1] = environment.CreateNumber(i); var value = callbackfn.Call(environment, thisArg, environment.CreateArgs(callArgs)); result.DefineOwnProperty(key, environment.CreateDataDescriptor(value, true, true, true), false); } } return result; }
private static IDynamic Filter(IEnvironment environment, IArgs args) { var result = ((IConstructable)environment.ArrayConstructor).Construct(environment, environment.EmptyArgs); var obj = environment.Context.ThisBinding.ConvertToObject(); var length = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; var thisArg = args[1]; if (callbackfn == null) throw environment.CreateTypeError(""); for (uint i = 0; i < length; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { var value = obj.Get(key); var callArgs = environment.CreateArgs(new[] { value, environment.CreateNumber(i), obj }); var include = callbackfn.Call(environment, thisArg, callArgs); if (include.ConvertToBoolean().BaseValue) { result.DefineOwnProperty(key, environment.CreateDataDescriptor(value, true, true, true), false); } } } return result; }
private static IDynamic Some(IEnvironment environment, IArgs args) { var obj = environment.Context.ThisBinding.ConvertToObject(); var callArgs = new IDynamic[] { null, null, obj }; var length = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var callbackfn = args[0] as ICallable; var thisArg = args[1]; if (callbackfn == null) { throw environment.CreateTypeError("The first parameter 'callbackfn' must be callable."); } for (uint i = 0; i < length; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { callArgs[0] = obj.Get(key); callArgs[1] = environment.CreateNumber(i); if (callbackfn.Call(environment, thisArg, environment.CreateArgs(callArgs)).ConvertToBoolean().BaseValue) { return environment.True; } } } return environment.False; }
internal static IDynamic Now(IEnvironment environment, IArgs args) { var value = environment.CreateNumber((DateTime.UtcNow - _utcStart).TotalMilliseconds); var constructArgs = environment.CreateArgs(new IDynamic[] { value }); return ((IConstructable)environment.DateConstructor).Construct(environment, constructArgs); }
private static IDynamic Call(IEnvironment environment, IArgs args) { var callable = environment.Context.ThisBinding as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var thisArg = args[0]; var callArgs = environment.EmptyArgs; if (args.Count > 1) { callArgs = environment.CreateArgs(args.Skip(1)); } return callable.Call(environment, thisArg, callArgs); }
private static IDynamic Sort(IEnvironment environment, IArgs args) { var obj = environment.Context.ThisBinding.ConvertToObject(); var len = (uint)obj.Get("length").ConvertToUInt32().BaseValue; var comparefn = args[0]; var sortCompare = new Func<uint, uint, IDynamic>((j, k) => { var jString = j.ToString(); var kString = k.ToString(); var hasJ = obj.HasProperty(jString); var hasK = obj.HasProperty(kString); if (!hasJ || !hasK) { if (!hasJ && !hasK) return environment.CreateNumber(0); else if (!hasJ) return environment.CreateNumber(1); else return environment.CreateNumber(-1); } var x = obj.Get(jString); var y = obj.Get(kString); if (x is IUndefined || y is IUndefined) { if (x is IUndefined && y is IUndefined) return environment.CreateNumber(0); else if (x is IUndefined) return environment.CreateNumber(1); else return environment.CreateNumber(-1); } if (comparefn.TypeCode != LanguageTypeCode.Undefined) { var callable = comparefn as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } return callable.Call(environment, environment.Undefined, environment.CreateArgs(new[] { x, y })); } var xString = x.ConvertToString(); var yString = y.ConvertToString(); var xLess = xString.Op_Lessthan(yString); if (((IBoolean)xLess).BaseValue) return environment.CreateNumber(-1); var yLess = yString.Op_Lessthan(xString); if (((IBoolean)yLess).BaseValue) return environment.CreateNumber(1); return environment.CreateNumber(0); }); var items = new List<IDynamic>(); for (uint i = 0; i < len; i++) { var key = i.ToString(); if (obj.HasProperty(key)) { var value = obj.Get(key); items.Add(value); obj.Delete(key, true); } } items.Sort((x, y) => { if (x is IUndefined || y is IUndefined) { if (x is IUndefined && y is IUndefined) return 0; else if (x is IUndefined) return 1; else return -1; } if (comparefn.TypeCode != LanguageTypeCode.Undefined) { var callable = comparefn as ICallable; if (callable == null) { throw environment.CreateTypeError(""); } var result = callable.Call(environment, environment.Undefined, environment.CreateArgs(new[] { x, y })); var number = result.ConvertToInteger(); if (double.IsNaN(number.BaseValue) || double.IsInfinity(number.BaseValue)) { return 0; } return (int)number.BaseValue; } var xString = x.ConvertToString(); var yString = y.ConvertToString(); var xLess = xString.Op_Lessthan(yString); if (((IBoolean)xLess).BaseValue) return -1; var yLess = yString.Op_Lessthan(xString); if (((IBoolean)yLess).BaseValue) return 1; return 0; }); for (int i = 0; i < items.Count; i++) { var key = i.ToString(); obj.Put(key, items[i], true); } return obj; }
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 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 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 Replace(IEnvironment environment, IArgs args) { var so = environment.Context.ThisBinding.ConvertToString(); var s = so.BaseValue; var sb = new StringBuilder(); var searchValueArg = args[0]; var replaceValueArg = args[1]; var replaceValueFunc = replaceValueArg as ICallable; var replaceValueString = replaceValueArg.ConvertToString(); var matchSubstring = ""; var i = 0; if (searchValueArg is NRegExp) { var regExpObj = (NRegExp)searchValueArg; var matcher = regExpObj.RegExpMatcher; Func <int, RegExpParser.MatchState, Func <string, string> > makeReplacer = null; if (replaceValueFunc != null) { makeReplacer = (startIndex, state) => v => { var cArgs = new List <IDynamic>(); cArgs.Add(environment.CreateString(v)); foreach (var c in state.captures) { cArgs.Add(c == null ? (IDynamic)environment.Null : environment.CreateString(c)); } cArgs.Add(environment.CreateNumber(startIndex)); cArgs.Add(so); var result = replaceValueFunc.Call( environment, environment.Undefined, environment.CreateArgs(cArgs) ); return(result.ConvertToString().BaseValue); }; } else { var replacer = MakeReplacer(replaceValueString.BaseValue); makeReplacer = (_, state) => v => replacer(v, state); } var global = regExpObj.Flags.Contains("g"); i = global ? (int)regExpObj.Get("lastIndex").ConvertToNumber().BaseValue : 0; do { var r = matcher(s, i); if (!r.success) { sb.Append(s[i++]); continue; } matchSubstring = s.Substring(i, r.matchState.endIndex - i); sb.Append(makeReplacer(i, r.matchState)(matchSubstring)); if (!global) { break; } i = r.matchState.endIndex; regExpObj.Put("lastIndex", environment.CreateNumber(i), false); } while (i < s.Length); } else { Func <string, string> replace = null; if (replaceValueFunc == null) { replace = v => replaceValueString.BaseValue; } else { replace = v => replaceValueFunc.Call( environment, environment.Undefined, environment.CreateArgs( new[] { environment.CreateString(v) } ) ) .ConvertToString() .BaseValue; } var searchValue = args[0].ConvertToString().BaseValue; var index = 0; do { var resultIndex = s.IndexOf(searchValue, index); if (resultIndex < 0) { sb.Append(s.Substring(index)); break; } matchSubstring = s.Substring(resultIndex, searchValue.Length); sb.Append(replace(matchSubstring)); index = resultIndex + searchValue.Length; } while (index < s.Length); } return(environment.CreateString(sb.ToString())); }