Beispiel #1
0
 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);
 }
Beispiel #2
0
        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());
            }
        }