public virtual DekiScriptLiteral EvaluateProperty(Location location, DekiScriptLiteral value, DekiScriptEnv env) { if (IsProperty(value)) { DekiScriptUri uri = (DekiScriptUri)value; try { value = Invoke(location, uri.Value, uri.Arguments.IsNil ? _emptyList : uri.Arguments, env); } catch (DekiScriptFatalException) { throw; } catch (Exception e) { var descriptor = ResolveRegisteredFunctionUri(uri.Value); throw new DekiScriptInvokeException(location, uri.Value, (descriptor != null) ? descriptor.Name : uri.Value.ToString(), e); } } return(value); }
private void AddUri(XmlNode context, DekiScriptUri uri) { if (context == null) { ConvertStateToHtml(null); } // NOTE (steveb): URIs have special embedding rules; either embed it as a <img> and <a> document base on the URI file extension on the last segment XUri url = uri.Value.AsPublicUri(); MimeType mime = (url.Segments.Length > 0) ? MimeType.FromFileExtension(url.LastSegment ?? string.Empty) : MimeType.BINARY; XDoc item = mime.MainType.EqualsInvariant("image") ? DekiScriptLibrary.WebImage(url.ToString(), null, null, null) : DekiScriptLibrary.WebLink(url.ToString(), null, null, null); AddXDoc(context, item); }
public DekiScriptExpression Visit(DekiScriptUri expr, DekiScriptExpressionEvaluationState state) { return(expr); }
private void AddUri(XmlNode context, DekiScriptUri uri) { if(context == null) { ConvertStateToHtml(null); } // NOTE (steveb): URIs have special embedding rules; either embed it as a <img> and <a> document base on the URI file extension on the last segment XUri url = uri.Value.AsPublicUri(); MimeType mime = (url.Segments.Length > 0) ? MimeType.FromFileExtension(url.LastSegment ?? string.Empty) : MimeType.BINARY; XDoc item = mime.MainType.EqualsInvariant("image") ? DekiScriptLibrary.WebImage(url.ToString(), null, null, null) : DekiScriptLibrary.WebLink(url.ToString(), null, null, null); AddXDoc(context, item); }
internal DekiScriptLiteral Evaluate(DekiScriptAccess expr, DekiScriptExpressionEvaluationState state, bool evaluateProperties) { DekiScriptLiteral prefix = state.Pop(expr.Prefix.VisitWith(this, state)); DekiScriptLiteral index = state.Pop(expr.Index.VisitWith(this, state)); switch (prefix.ScriptType) { case DekiScriptType.MAP: { DekiScriptLiteral result = ((DekiScriptMap)prefix)[index]; if (evaluateProperties) { result = state.Runtime.EvaluateProperty(expr.Location, result, state.Env); } return(result); } case DekiScriptType.LIST: { DekiScriptLiteral value = DekiScriptExpression.Constant(index.AsNumber()); DekiScriptLiteral result = ((DekiScriptList)prefix)[value]; if (evaluateProperties) { result = state.Runtime.EvaluateProperty(expr.Location, result, state.Env); } return(result); } case DekiScriptType.URI: { DekiScriptUri uri = (DekiScriptUri)prefix; // coerce the index type to STR index = DekiScriptExpression.Constant(index.AsString()); if (index.ScriptType != DekiScriptType.STR) { throw new DekiScriptBadTypeException(expr.Location, index.ScriptType, new[] { DekiScriptType.STR }); } // curry the argument DekiScriptList args; if (!uri.Arguments.IsNil) { // the uri already has curried parameters, make sure they are in LIST format; otherwise fail if (uri.Arguments.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadTypeException(expr.Location, uri.Arguments.ScriptType, new[] { DekiScriptType.NIL, DekiScriptType.LIST }); } args = new DekiScriptList((DekiScriptList)uri.Arguments); } else { args = new DekiScriptList(); } args.Add(index); return(new DekiScriptUri(uri.Value, args)); } case DekiScriptType.STR: { DekiScriptString text = (DekiScriptString)prefix; // coerce the index type to NUM double?value = index.AsNumber(); if (value == null) { throw new DekiScriptBadTypeException(expr.Location, index.ScriptType, new[] { DekiScriptType.NUM }); } // retrieve character at given index position int position = (int)value; if ((position < 0) || (position >= text.Value.Length)) { // index is out of bounds, return nil return(DekiScriptNil.Value); } return(DekiScriptExpression.Constant(text.Value[position].ToString())); } case DekiScriptType.XML: { string path = index.AsString(); if (path == null) { throw new DekiScriptBadTypeException(expr.Location, index.ScriptType, new[] { DekiScriptType.STR }); } XDoc doc = ((DekiScriptXml)prefix).Value[path]; if (doc.HasName("html")) { doc = DekiScriptLibrary.CleanseHtmlDocument(doc); } return(new DekiScriptXml(doc)); } case DekiScriptType.NIL: return(DekiScriptNil.Value); } throw new DekiScriptBadTypeException(expr.Location, prefix.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST, DekiScriptType.XML, DekiScriptType.STR, DekiScriptType.URI }); }
public DekiScriptOutputBuffer.Range Visit(DekiScriptUri expr, DekiScriptExpressionEvaluationState state) { return(state.Push(expr)); }
public DekiScriptOutputBuffer.Range Visit(DekiScriptCall expr, DekiScriptExpressionEvaluationState state) { state.ThrowIfTimedout(); // evaluate prefix DekiScriptLiteral prefix = state.Pop(expr.Prefix.VisitWith(this, state)); if (prefix.ScriptType != DekiScriptType.URI) { if (prefix.ScriptType == DekiScriptType.NIL) { throw new DekiScriptUndefinedNameException(expr.Location, expr.Prefix.ToString()); } else { throw new DekiScriptBadTypeException(expr.Location, prefix.ScriptType, new[] { DekiScriptType.URI }); } } // evaluate arguments DekiScriptLiteral arguments = state.Pop(expr.Arguments.VisitWith(this, state)); if ((arguments.ScriptType != DekiScriptType.MAP) && (arguments.ScriptType != DekiScriptType.LIST)) { throw new DekiScriptBadTypeException(expr.Location, arguments.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST }); } // check if the URI was curried DekiScriptUri uri = (DekiScriptUri)prefix; if (!uri.Arguments.IsNil) { switch (uri.Arguments.ScriptType) { case DekiScriptType.LIST: // append argument to list DekiScriptList list = new DekiScriptList((DekiScriptList)uri.Arguments); list.Add(arguments); arguments = list; break; case DekiScriptType.MAP: if (arguments.ScriptType == DekiScriptType.MAP) { // concatenate both maps DekiScriptMap map = new DekiScriptMap(); map.AddRange((DekiScriptMap)uri.Arguments); map.AddRange((DekiScriptMap)arguments); arguments = map; } else if ((arguments.ScriptType != DekiScriptType.LIST) || ((DekiScriptList)arguments).Value.Count > 0) { // we can't append a list to a map throw new DekiScriptBadTypeException(expr.Location, arguments.ScriptType, new[] { DekiScriptType.MAP }); } break; default: throw new DekiScriptBadTypeException(expr.Location, arguments.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST }); } } // check if this is an invocation or curry operation if (expr.IsCurryOperation) { return(state.Push(new DekiScriptUri(uri.Value, arguments))); } // invoke function try { return(state.Push(state.Runtime.Invoke(expr.Location, uri.Value, arguments, state.Env))); } catch (DekiScriptFatalException) { throw; } catch (Exception e) { var descriptor = state.Runtime.ResolveRegisteredFunctionUri(uri.Value); throw new DekiScriptInvokeException(expr.Location, uri.Value, (descriptor != null) ? descriptor.Name : uri.Value.ToString(), e); } }
public DekiScriptExpression Visit(DekiScriptUri expr, DekiScriptOptimizerState state) { return(expr); }
public DekiScriptLiteral Visit(DekiScriptUri expr, DekiScriptEnv env) { return(expr); }
public DekiScriptLiteral Visit(DekiScriptCall expr, DekiScriptEnv env) { // evaluate prefix DekiScriptLiteral prefix = expr.Prefix.VisitWith(this, env); if (prefix.ScriptType != DekiScriptType.URI) { if (prefix.ScriptType == DekiScriptType.NIL) { throw new DekiScriptUndefinedNameException(expr.Line, expr.Column, expr.Prefix.ToString()); } else { throw new DekiScriptBadTypeException(expr.Line, expr.Column, prefix.ScriptType, new DekiScriptType[] { DekiScriptType.URI }); } } // evaluate arguments DekiScriptLiteral arguments = expr.Arguments.VisitWith(this, env); if ((arguments.ScriptType != DekiScriptType.MAP) && (arguments.ScriptType != DekiScriptType.LIST)) { throw new DekiScriptBadTypeException(expr.Line, expr.Column, arguments.ScriptType, new DekiScriptType[] { DekiScriptType.MAP, DekiScriptType.LIST }); } // check if the URI was curried DekiScriptUri uri = (DekiScriptUri)prefix; if (!uri.Arguments.IsNil) { switch (uri.Arguments.ScriptType) { case DekiScriptType.LIST: // append argument to list DekiScriptList list = new DekiScriptList((DekiScriptList)uri.Arguments); list.Add(arguments); arguments = list; break; case DekiScriptType.MAP: if (arguments.ScriptType == DekiScriptType.MAP) { // concatenate both maps DekiScriptMap map = new DekiScriptMap(); map.AddRange((DekiScriptMap)uri.Arguments); map.AddRange((DekiScriptMap)arguments); arguments = map; } else if ((arguments.ScriptType != DekiScriptType.LIST) || ((DekiScriptList)arguments).Value.Count > 0) { // we can't append a list to a map throw new DekiScriptBadTypeException(expr.Line, expr.Column, arguments.ScriptType, new DekiScriptType[] { DekiScriptType.MAP }); } break; default: throw new DekiScriptBadTypeException(expr.Line, expr.Column, arguments.ScriptType, new DekiScriptType[] { DekiScriptType.MAP, DekiScriptType.LIST }); } } // check if this is an invocation or curry operation if (expr.IsCurryOperation) { return(new DekiScriptUri(uri.Value, arguments)); } else { // invoke function return(Coroutine.Invoke(DekiScriptRuntime.Invoke, uri.Value, arguments, env, new Result <DekiScriptLiteral>()).Wait()); } }