public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // make web-request DreamMessage response = plug.Post(args.ToXml(), new Tasking.Result<DreamMessage>()).Wait(); if(!response.IsSuccessful) { if(response.HasDocument) { var error = response.ToDocument(); var message = error["message"]; if(error.HasName("exception") && !message.IsEmpty) { throw new DekiScriptRemoteException(Location.None, message.Contents); } } throw new DreamResponseException(response); } // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch(ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if(list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return ((DekiScriptList)list)[0]; }
public static ArrayList ListSort( [DekiScriptParam("list of values")] ArrayList list, [DekiScriptParam("key for value if list contains maps (default: nil)", true)] object key, [DekiScriptParam("sort in reverse order (default: false)", true)] bool? reverse, [DekiScriptParam("compare two items (return -1 if left item less than the right item, 0 if they are equal, and +1 if the left item is greater than the right item; use '$left' and '$right' to refer to the left and right items respectively)", true)] string compare, DekiScriptRuntime runtime ) { // prepare custom comparer IComparer comparer = null; if(compare != null) { comparer = new DekiScriptComparer(runtime, DekiScriptParser.Parse(new Location("list.sort(compare)"), compare)); } // sort list if(key == null || (key as string != null && string.IsNullOrEmpty(key as string))) { list.Sort(comparer); } else { Array keys = (key is ArrayList) ? ((ArrayList)key).ToArray() : ListCollect(list, key.ToString(), runtime).ToArray(); Array values = list.ToArray(); Array.Sort(keys, values, comparer); list = new ArrayList(values); } // check if results need to be reveresed if(reverse ?? false) { list.Reverse(); } return list; }
private DekiScriptExpressionEvaluationState(DekiScriptEnv env, DekiScriptRuntime runtime, XmlNamespaceManager namespaces, DekiScriptOutputBuffer buffer, SharedState sharedState) { this.Env = env; this.Namespaces = namespaces; this.Buffer = buffer; this.Runtime = runtime; _sharedState = sharedState; }
public DekiScriptExpressionEvaluationState(DekiScriptEvalMode mode, DekiScriptEnv env, DekiScriptRuntime runtime, XmlNamespaceManager namespaces, DekiScriptOutputBuffer buffer) { this.Mode = mode; this.Env = env; this.Namespaces = namespaces; this.Buffer = buffer; this.Runtime = runtime; _safe = (mode == DekiScriptEvalMode.EvaluateSafeMode); }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) { // invoke script DekiScriptEnv env = (_env != null) ? _env.NewScope() : runtime.CreateEnv(); env.Vars.Add("args", args); env.Vars.Add("$", args); return runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env); }
//--- Constructor --- public DekiScriptExpressionEvaluationState(DekiScriptEvalMode mode, DekiScriptEnv env, DekiScriptRuntime runtime) { this.Mode = mode; this.Env = env; this.Namespaces = new XmlNamespaceManager(XDoc.XmlNameTable); this.Buffer = new DekiScriptOutputBuffer(); this.Runtime = runtime; _safe = (mode == DekiScriptEvalMode.EvaluateSafeMode); }
public static object JsonParse( [DekiScriptParam("value to convert", true)] string value, DekiScriptRuntime runtime ) { // TODO (steveb): 'json.parse' based on spec at http://json.org/ return StringDeserialize(value, runtime); }
//--- Methods --- public virtual DekiScriptLiteral Invoke(DekiScriptRuntime runtime, DekiScriptLiteral args) { if(args is DekiScriptList) { return InvokeList(runtime, (DekiScriptList)args); } else if(args is DekiScriptMap) { return InvokeMap(runtime, (DekiScriptMap)args); } else { throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST }); } }
private static object Eval(object value, DekiScriptRuntime runtime) { if(value is XUri) { DekiScriptLiteral uri = DekiScriptExpression.Constant((XUri)value); if(DekiScriptRuntime.IsProperty(uri)) { value = runtime.EvaluateProperty(Location.None, uri, runtime.CreateEnv()).NativeValue; } } return value; }
public static ArrayList ListOrderBy( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("key name or list of key names; sort direction is controlled by appendending \" ascending\" or \" descending\" to the key(s); when omitted, the direction is asending by default")] object keys, DekiScriptRuntime runtime ) { // check for trivial sort case if (keys is string) { string key = ((string)keys).Trim(); // the key cannot contain access operators if (key.IndexOfAny(new[] { '.', '[', ']' }) < 0) { return(ListOrderBy_IsReversed(ref key) ? ListSort(list, key, true, null, runtime) : ListSort(list, key, false, null, runtime)); } // let's change 'keys' into an array list for processing convenience ArrayList temp = new ArrayList { keys }; keys = temp; } // check that 'keys' has a valid type if (!(keys is ArrayList)) { throw new DekiScriptBadTypeException(Location.None, DekiScriptLiteral.AsScriptType(keys.GetType()), new[] { DekiScriptType.STR, DekiScriptType.LIST }); } // build comparison expression StringBuilder compare = new StringBuilder(); foreach (string key in (ArrayList)keys) { if (compare.Length > 0) { compare.Append(" || "); } // process sort field string field = key; if (ListOrderBy_IsReversed(ref field)) { compare.AppendFormat("(if($left.{0} < $right.{0}) 1; else if($left.{0} > $right.{0}) -1; else 0;)", field); } else { compare.AppendFormat("(if($left.{0} < $right.{0}) -1; else if($left.{0} > $right.{0}) 1; else 0;)", field); } } // sort list list.Sort(new DekiScriptComparer(runtime, DekiScriptParser.Parse(new Location("list.orderby(compare)"), compare.ToString()))); return(list); }
//--- Constructors --- public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare) { if(compare == null) { throw new ArgumentNullException("compare"); } _runtime = runtime; _compare = compare; _values = new DekiScriptMap(); _env = runtime.CreateEnv(); _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values); }
protected override Yield Stop(Result result) { _scriptEnv = null; _runtime = null; _functions.Clear(); _files.Clear(); yield return(Coroutine.Invoke(base.Stop, new Result())); result.Return(); }
public static ArrayList MapValues( [DekiScriptParam("map value")] Hashtable map, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(map.Values); for(int i = 0; i < result.Count; ++i) { result[i] = Eval(result[i], runtime); } return result; }
private static object Eval(object value, DekiScriptRuntime runtime) { if (value is XUri) { DekiScriptLiteral uri = DekiScriptExpression.Constant((XUri)value); if (DekiScriptRuntime.IsProperty(uri)) { value = runtime.EvaluateProperty(Location.None, uri, runtime.CreateEnv()).NativeValue; } } return(value); }
//--- Constructors --- public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare) { if (compare == null) { throw new ArgumentNullException("compare"); } _runtime = runtime; _compare = compare; _values = new DekiScriptMap(); _env = runtime.CreateEnv(); _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values); }
public static ArrayList MapValues( [DekiScriptParam("map value")] Hashtable map, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(map.Values); // HACK (steveb): pro-actively evaluate properties for(int i = 0; i < result.Count; ++i) { result[i] = Eval(result[i], runtime); } return result; }
//--- Constructor --- public DekiScriptExpressionEvaluationState(DekiScriptEvalMode mode, DekiScriptEnv env, DekiScriptRuntime runtime, TimeSpan evaluationTimeout, int maxOutputBufferSize) { this.Env = env; this.Namespaces = new XmlNamespaceManager(XDoc.XmlNameTable); this.Buffer = new DekiScriptOutputBuffer(maxOutputBufferSize); this.Runtime = runtime; _sharedState = new SharedState(); _sharedState.Safe = (mode == DekiScriptEvalMode.EvaluateSafeMode); if(evaluationTimeout == TimeSpan.MaxValue) { return; } _sharedState.EvaluationTimeout = evaluationTimeout; _sharedState.EvaluationTimer = Stopwatch.StartNew(); }
public static ArrayList MapValues( [DekiScriptParam("map value")] Hashtable map, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(map.Values); for (int i = 0; i < result.Count; ++i) { result[i] = Eval(result[i], runtime); } return(result); }
private void InitializeRuntimeAndEnvironment() { if (_runtime != null) { return; } lock (_functions) { if (_runtime == null) { _runtime = new DekiScriptRuntime(); _scriptEnv = InitializeRuntimeAndEnvironment(_runtime); } } }
//--- Constructor --- public DekiScriptExpressionEvaluationState(DekiScriptEvalMode mode, DekiScriptEnv env, DekiScriptRuntime runtime, TimeSpan evaluationTimeout, int maxOutputBufferSize) { this.Env = env; this.Namespaces = new XmlNamespaceManager(XDoc.XmlNameTable); this.Buffer = new DekiScriptOutputBuffer(maxOutputBufferSize); this.Runtime = runtime; _sharedState = new SharedState(); _sharedState.Safe = (mode == DekiScriptEvalMode.EvaluateSafeMode); if (evaluationTimeout == TimeSpan.MaxValue) { return; } _sharedState.EvaluationTimeout = evaluationTimeout; _sharedState.EvaluationTimer = Stopwatch.StartNew(); }
//--- Methods --- public virtual DekiScriptLiteral Invoke(DekiScriptRuntime runtime, DekiScriptLiteral args) { if (args is DekiScriptList) { return(InvokeList(runtime, (DekiScriptList)args)); } else if (args is DekiScriptMap) { return(InvokeMap(runtime, (DekiScriptMap)args)); } else { throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST }); } }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) { // invoke script DekiScriptEnv env = _env.NewScope(); env.Vars.AddRange(DreamContext.Current.GetState <DekiScriptMap>("env.implicit")); env.Vars.Add("args", args); env.Vars.Add("$", args); var result = runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env); try { return(result.Convert(_returnType)); } catch (DekiScriptInvalidCastException) { throw new DekiScriptInvalidReturnCastException(Location.None, result.ScriptType, _returnType); } }
public static ArrayList MapKeyValues( [DekiScriptParam("map value")] Hashtable map, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(map.Count); foreach (DictionaryEntry entry in map) { Hashtable keyvalue = new Hashtable(); keyvalue.Add("key", entry.Key); keyvalue.Add("value", Eval(entry.Value, runtime)); result.Add(keyvalue); } return(result); }
public static ArrayList ListApply( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to apply (use '$' to refer to the current item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.apply(expression)"), expression); ArrayList result = new ArrayList(); foreach (object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, DekiScriptLiteral.FromNativeValue(entry)); result.Add(runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue); } return(result); }
//--- Methods --- public override DekiScriptLiteral InvokeList(DekiScriptRuntime runtime, DekiScriptList args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); DreamMessage response = plug.Post(DekiScriptToXmlRpc(_methodname, args)); // convert response to literal DekiScriptLiteral list = FromXmlRpcToDekiScript(response.ToDocument()); if (list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return(((DekiScriptList)list)[0]); }
public static Hashtable MapApply( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach(DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime))); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env)); } return result; }
public DekiScriptEnv InitializeRuntimeAndEnvironment(DekiScriptRuntime runtime) { runtime.RegisterExtensionFunctions(_functions); // initialize evaluation environment var env = runtime.CreateEnv(); // add extension functions to env foreach (var function in _functions) { if (!function.Value.IsProperty || (function.Value.Parameters.Length == 0)) { env.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key); } } env.Vars.Add("config", _scriptConfig); return(env); }
private void InitScriptRuntimeAndEnv() { if (_runtime != null) { return; } // Note (arnec): have to lazily init the runtime and env, because they require instance settings and they currently have // a requirement of DekiContext.Current.Instance being set, i.e. a race condition in the ctor lock (SettingsSyncRoot) { if (_runtime != null) { return; } _runtime = new ExtensionRuntime(new DekiInstanceSettings()); _scriptEnv = _deki.InitializeRuntimeAndEnvironment(_runtime); } }
public static ArrayList ListIntersect( [DekiScriptParam("first list")] ArrayList first, [DekiScriptParam("second list")] ArrayList second, [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); if (condition != null) { // loop over both lists and keep items from the first list based on the outcome of the condition DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition); foreach (object left in first) { foreach (object right in second) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left)); keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if (!test.IsNilFalseZero) { result.Add(left); break; } } } } else { // using simple containment check to keep items foreach (object item in first) { if (second.Contains(item)) { result.Add(item); } } } return(result); }
//--- Class Methods --- public static string Parse(string code, string id, DekiScriptEnv env, DekiScriptRuntime runtime) { StringBuilder result = new StringBuilder(); // check if code is attached to an id'ed element if(!string.IsNullOrEmpty(id)) { result.AppendLine("$(\"#" + id + "\").each(function() {"); result.AppendLine("var $this = $(this);"); } // convert JEM code into regular javascript int i = 0; result.Append(ParseExpression(code, id, ParseMode.ALL, false, env, runtime, new Dictionary<string, string>(), ref i)); // check if code is attached to an id'ed element if(!string.IsNullOrEmpty(id)) { result.AppendLine("});"); } return result.ToString(); }
public static object StringEval( [DekiScriptParam("dekiscript expression")] string code, [DekiScriptParam("ignore errors during evaluation", true)] bool?ignoreErrors, DekiScriptRuntime runtime ) { try { return(runtime.Evaluate(DekiScriptParser.Parse(new Location("string.eval(code)"), code), DekiScriptEvalMode.EvaluateSafeMode, runtime.CreateEnv()).NativeValue); } catch (Exception e) { if (ignoreErrors ?? false) { return(e.ToString()); } else { throw; } } }
public static ArrayList ListCollect( [DekiScriptParam("list of maps")] ArrayList list, [DekiScriptParam("key for value to collect")] string key, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); foreach (object entry in list) { Hashtable map = entry as Hashtable; if ((map != null) && map.ContainsKey(key)) { object value = map[key]; result.Add(Eval(value, runtime)); } } return(result); }
public static Hashtable MapApply( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime))); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env)); } return(result); }
public DekiScriptLiteral Visit(DekiScriptVar expr, DekiScriptEnv env) { if (expr.Name.EqualsInvariant(DekiScriptRuntime.ENV_ID)) { DekiScriptMap vars = new DekiScriptMap(); vars.AddRange(env.Globals); vars.AddRange(env.Locals); return(vars); } // check if variable exists DekiScriptLiteral result = env[expr.Name]; if (result == null) { throw new DekiScriptUndefinedNameException(expr.Line, expr.Column, expr.Name); } result = DekiScriptRuntime.EvaluateProperty(result, env); return(result); }
public static object ListReduce( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression, [DekiScriptParam("starting value (default: nil)", true)] object value, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression); foreach (object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap values = new DekiScriptMap(); values.Add("value", DekiScriptLiteral.FromNativeValue(value)); values.Add("item", DekiScriptLiteral.FromNativeValue(entry)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values); value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue; } return(value); }
public static double ListMax( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to fetch value (use '$' to refer to the current item; default: $)", true)] string expression, DekiScriptRuntime runtime ) { if (expression != null) { list = ListApply(list, expression, runtime); } double result = double.MinValue; foreach (object entry in list) { try { result = Math.Max(result, SysUtil.ChangeType <double>(entry)); } catch { } } return(result); }
public object WebJson( [DekiExtParam("source text or source uri (default: none)", true)] string source, [DekiExtParam("caching duration in seconds (range: 300+; default: 300)", true)] double?ttl, [DekiExtParam("return nil if source could not be loaded (default: text with error message)", true)] bool?nilIfMissing, DekiScriptRuntime runtime ) { source = source ?? string.Empty; XUri uri = XUri.TryParse(source); if (uri == null) { return(DekiScriptLibrary.JsonParse(source, runtime)); } // we need to fetch an online document string response = CachedWebGet(uri, ttl, nilIfMissing); return(DekiScriptLibrary.JsonParse(response, runtime)); }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // invoke function DreamMessage response = plug.Get(); // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch(ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if(list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return ((DekiScriptList)list)[0]; }
public static Hashtable MapFilter( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.select(condition)"), condition); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach(DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); object value = Eval(entry.Value, runtime); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value)); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { result.Add(entry.Key, value); } } return result; }
public static int ListCount( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("condition to execute for each item (use '$' to refer to the item)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.count(condition)"), condition); int count = 0; foreach (object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, DekiScriptLiteral.FromNativeValue(entry)); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if (!test.IsNilFalseZero) { ++count; } } return(count); }
public static double ListAverage( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to fetch value (use '$' to refer to the current item; default: $)", true)] string expression, DekiScriptRuntime runtime ) { if (expression != null) { list = ListApply(list, expression, runtime); } double result = 0.0; int count = 0; foreach (object entry in list) { try { result += SysUtil.ChangeType <double>(entry); ++count; } catch { } } return((count > 0) ? (result / count) : 0.0); }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // make web-request DreamMessage response = plug.Post(args.ToXml(), new Tasking.Result <DreamMessage>()).Wait(); if (!response.IsSuccessful) { if (response.HasDocument) { var error = response.ToDocument(); var message = error["message"]; if (error.HasName("exception") && !message.IsEmpty) { throw new DekiScriptRemoteException(Location.None, message.Contents); } } throw new DreamResponseException(response); } // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch (ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if (list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return(((DekiScriptList)list)[0]); }
protected override Yield Stop(Result result) { _publicDigitalSignature = null; _manifestPath = null; _resourcesPath = null; _manifestUri = null; _resourcesUri = null; _manifest = null; _debug = false; _runtime = null; _commonEnv = null; _copyright = null; _description = null; _functions = null; _help = null; _label = null; _logo = null; _namespace = null; _title = null; yield return(Coroutine.Invoke(base.Stop, new Result())); result.Return(); }
//--- Class Methods --- public static string Parse(string code, string id, DekiScriptEnv env, DekiScriptRuntime runtime) { StringBuilder result = new StringBuilder(); // check if code is attached to an id'ed element if (!string.IsNullOrEmpty(id)) { result.AppendLine("$(\"#" + id + "\").each(function() {"); result.AppendLine("var $this = $(this);"); } // convert JEM code into regular javascript int i = 0; result.Append(ParseExpression(code, id, ParseMode.ALL, false, env, runtime, new Dictionary <string, string>(), ref i)); // check if code is attached to an id'ed element if (!string.IsNullOrEmpty(id)) { result.AppendLine("});"); } return(result.ToString()); }
public static ArrayList ListSort( [DekiScriptParam("list of values")] ArrayList list, [DekiScriptParam("key for value if list contains maps (default: nil)", true)] object key, [DekiScriptParam("sort in reverse order (default: false)", true)] bool?reverse, [DekiScriptParam("compare two items (return -1 if left item less than the right item, 0 if they are equal, and +1 if the left item is greater than the right item; use '$left' and '$right' to refer to the left and right items respectively)", true)] string compare, DekiScriptRuntime runtime ) { // prepare custom comparer IComparer comparer = null; if (compare != null) { comparer = new DekiScriptComparer(runtime, DekiScriptParser.Parse(new Location("list.sort(compare)"), compare)); } // sort list if (key == null || (key as string != null && string.IsNullOrEmpty(key as string))) { list.Sort(comparer); } else { Array keys = (key is ArrayList) ? ((ArrayList)key).ToArray() : ListCollect(list, key.ToString(), runtime).ToArray(); Array values = list.ToArray(); Array.Sort(keys, values, comparer); list = new ArrayList(values); } // check if results need to be reveresed if (reverse ?? false) { list.Reverse(); } return(list); }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // invoke function DreamMessage response = plug.Get(); // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch (ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if (list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return(((DekiScriptList)list)[0]); }
public DekiScriptExpression Visit(DekiScriptAccess expr, DekiScriptOptimizerState state) { DekiScriptExpression prefix = expr.Prefix.VisitWith(this, state); DekiScriptExpression index = expr.Index.VisitWith(this, state); DekiScriptAccess access = new DekiScriptAccess(expr.Line, expr.Column, prefix, index); if ((prefix is DekiScriptLiteral) && (index is DekiScriptLiteral)) { // BUGBUGBUG (steveb): don't eval properties! DekiScriptLiteral result = DekiScriptExpressionEvaluation.Instance.Evaluate(access, state.Env, false); // check if result is a property if (DekiScriptRuntime.IsProperty(result)) { // retrieve property information DekiScriptFunction function; if (DekiScriptLibrary.Functions.TryGetValue(((DekiScriptUri)result).Value, out function)) { if (function is DekiScriptFunctionNative) { DekiScriptFunctionNative native = (DekiScriptFunctionNative)function; // check if function is idempotent; if so, execute it if (native.IsIdempotent) { // evaluate property, since it never changes return(DekiScriptRuntime.EvaluateProperty(result, state.Env)); } } } return(new DekiScriptCall(expr.Line, expr.Column, result, new DekiScriptList(), false)); } return(result); } return(access); }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptList args) { // convert passed in arguments object[] arguments = new object[Parameters.Length]; int i = 0; try { for(; i < Parameters.Length; ++i) { var value = args[i].NativeValue; // check if we need to convert the value if((value != null) && (Parameters[i].NativeType != typeof(object))) { // check for the special case where we cast from XML to STR if((value is XDoc) && (Parameters[i].NativeType == typeof(string))) { XDoc xml = (XDoc)value; if(xml.HasName("html")) { value = xml["body[not(@target)]"].Contents; } else { value = xml.ToString(); } } else { // rely on the default type conversion rules value = SysUtil.ChangeType(value, Parameters[i].NativeType); } } arguments[i] = value; } } catch { throw new ArgumentException(string.Format("could not convert parameter '{0}' (index {1}) from {2} to {3}", Parameters[i].Name, i, args[i].ScriptTypeName, DekiScriptLiteral.AsScriptTypeName(Parameters[i].ScriptType))); } // invoke method var result = _invoke(runtime, arguments); // check if result is a URI if(result is XUri) { // normalize URI if possible DreamContext context = DreamContext.CurrentOrNull; if(context != null) { result = context.AsPublicUri((XUri)result); } } var literal = DekiScriptLiteral.FromNativeValue(result); try { return literal.Convert(ReturnType); } catch(DekiScriptInvalidCastException) { throw new DekiScriptInvalidReturnCastException(Location.None, literal.ScriptType, ReturnType); } }
public static object ListReduce( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression, [DekiScriptParam("starting value (default: nil)", true)] object value, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression); foreach(object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap values = new DekiScriptMap(); values.Add("value", DekiScriptLiteral.FromNativeValue(value)); values.Add("item", DekiScriptLiteral.FromNativeValue(entry)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values); value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue; } return value; }
public static ArrayList ListIntersect( [DekiScriptParam("first list")] ArrayList first, [DekiScriptParam("second list")] ArrayList second, [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); if(condition != null) { // loop over both lists and keep items from the first list based on the outcome of the condition DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition); foreach(object left in first) { foreach(object right in second) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left)); keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { result.Add(left); break; } } } } else { // using simple containment check to keep items foreach(object item in first) { if(second.Contains(item)) { result.Add(item); } } } return result; }
public static object WebJson( [DekiScriptParam("source text or source uri (default: none)", true)] string source, [DekiScriptParam("caching duration in seconds (range: 60 - 86400; default: 300)", true)] double? ttl, DekiScriptRuntime runtime ) { source = source ?? string.Empty; XUri uri = XUri.TryParse(source); if(uri == null) { return JsonParse(source, runtime); } // we need to fetch an online document string response = CachedWebGet(uri, ttl); return JsonParse(response, runtime); }
public static ArrayList ListOrderBy( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("key name or list of key names; sort direction is controlled by appendending \" ascending\" or \" descending\" to the key(s); when omitted, the direction is asending by default")] object keys, DekiScriptRuntime runtime ) { // check for trivial sort case if(keys is string) { string key = ((string)keys).Trim(); // the key cannot contain access operators if(key.IndexOfAny(new[] { '.', '[', ']' }) < 0) { return ListOrderBy_IsReversed(ref key) ? ListSort(list, key, true, null, runtime) : ListSort(list, key, false, null, runtime); } // let's change 'keys' into an array list for processing convenience ArrayList temp = new ArrayList { keys }; keys = temp; } // check that 'keys' has a valid type if(!(keys is ArrayList)) { throw new DekiScriptBadTypeException(Location.None, DekiScriptLiteral.AsScriptType(keys.GetType()), new[] { DekiScriptType.STR, DekiScriptType.LIST }); } // build comparison expression StringBuilder compare = new StringBuilder(); foreach(string key in (ArrayList)keys) { if(compare.Length > 0) { compare.Append(" || "); } // process sort field string field = key; if(ListOrderBy_IsReversed(ref field)) { compare.AppendFormat("(if($left.{0} < $right.{0}) 1; else if($left.{0} > $right.{0}) -1; else 0;)", field); } else { compare.AppendFormat("(if($left.{0} < $right.{0}) -1; else if($left.{0} > $right.{0}) 1; else 0;)", field); } } // sort list list.Sort(new DekiScriptComparer(runtime, DekiScriptParser.Parse(new Location("list.orderby(compare)"), compare.ToString()))); return list; }
public static object WebJson( [DekiScriptParam("source text or source uri (default: none)", true)] string source, [DekiScriptParam("caching duration in seconds (range: 60 - 86400; default: 300)", true)] double? ttl, DekiScriptRuntime runtime ) { return WebJson(source, ttl, null, runtime); }
public static double ListAverage( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to fetch value (use '$' to refer to the current item; default: $)", true)] string expression, DekiScriptRuntime runtime ) { if(expression != null) { list = ListApply(list, expression, runtime); } double result = 0.0; int count = 0; foreach(object entry in list) { try { result += SysUtil.ChangeType<double>(entry); ++count; } catch { } } return (count > 0) ? (result / count) : 0.0; }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { return InvokeHelper(runtime, DekiScriptParameter.ValidateToList(Parameters, args)); }
public static Hashtable ListGroupBy( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to apply for grouping (use '$' to refer to the current item)")] string expression, DekiScriptRuntime runtime ) { Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.groupby(expression)"), expression); // loop over all items in list foreach(object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, DekiScriptLiteral.FromNativeValue(entry)); // evalute grouping expression string key = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).AsString(); if(key != null) { // check if an accumulation list already exists; otherwise, create one ArrayList accumulator = (ArrayList)result[key]; if(accumulator == null) { accumulator = new ArrayList(); result[key] = accumulator; } accumulator.Add(entry); } } return result; }
public static double ListMax( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to fetch value (use '$' to refer to the current item; default: $)", true)] string expression, DekiScriptRuntime runtime ) { if(expression != null) { list = ListApply(list, expression, runtime); } double result = double.MinValue; foreach(object entry in list) { try { result = Math.Max(result, SysUtil.ChangeType<double>(entry)); } catch { } } return result; }
//--- Methods --- public override DekiScriptLiteral InvokeList(DekiScriptRuntime runtime, DekiScriptList args) { throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.MAP }); }
public static object WebJson( [DekiScriptParam("source text or source uri (default: none)", true)] string source, [DekiScriptParam("caching duration in seconds (range: 60 - 86400; default: 300)", true)] double? ttl, [DekiScriptParam("return nil if source could not be loaded (default: text with error message)", true)] bool? nilIfMissing, DekiScriptRuntime runtime ) { source = source ?? string.Empty; XUri uri = XUri.TryParse(source); if(uri == null) { return JsonParse(source, runtime); } // we need to fetch an online document string response = CachedWebGet(uri, ttl, nilIfMissing); if(response == null) { return null; } return JsonParse(response, runtime); }
public static int ListCount( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("condition to execute for each item (use '$' to refer to the item)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.count(condition)"), condition); int count = 0; foreach(object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, DekiScriptLiteral.FromNativeValue(entry)); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { ++count; } } return count; }