예제 #1
0
        public virtual int Write(ITemplateWriter @out, CultureInfo culture, ITemplateErrorListener listener)
        {
            Interpreter   interp = new Interpreter(Group, culture, new ErrorManager(listener), false);
            TemplateFrame frame  = new TemplateFrame(this, null);

            return(interp.Execute(@out, frame));
        }
예제 #2
0
 public virtual List<InterpEvent> GetEvents(CultureInfo culture, ITemplateWriter writer)
 {
     Interpreter interp = new Interpreter(Group, culture, true);
     TemplateFrame frame = new TemplateFrame(this, null);
     interp.Execute(writer, frame); // Render and track events
     return interp.GetEvents();
 }
예제 #3
0
        public virtual int Write(ITemplateWriter @out, CultureInfo culture)
        {
            Interpreter   interp = new Interpreter(Group, culture, impl.NativeGroup.ErrorManager, false);
            TemplateFrame frame  = new TemplateFrame(this, null);

            return(interp.Execute(@out, frame));
        }
예제 #4
0
 public object GetProperty(Interpreter interpreter, TemplateFrame frame, object o, object property, string propertyName)
 {
     if (propertyName.Equals("id"))
         return "const id value";
     if (propertyName.Equals("name"))
         return "const name value";
     throw new TemplateNoSuchPropertyException(null, "User." + propertyName);
 }
예제 #5
0
        public TemplateFrame(Template template, TemplateFrame parent)
        {
            _template = template;
            _parent = parent;

            _depth = (parent != null) ? parent._depth + 1 : 1;

            if (parent != null && parent._debugState != null && parent._debugState.IsEarlyEval)
                GetDebugState().IsEarlyEval = true;
        }
예제 #6
0
        public TemplateFrame(Template template, TemplateFrame parent)
        {
            _template = template;
            _parent   = parent;

            _depth = (parent != null) ? parent._depth + 1 : 1;

            if (parent != null && parent._debugState != null && parent._debugState.IsEarlyEval)
            {
                GetDebugState().IsEarlyEval = true;
            }
        }
예제 #7
0
        public List <TemplateFrame> GetFrameStack(bool topdown)
        {
            List <TemplateFrame> stack = new List <TemplateFrame>();

            for (TemplateFrame p = this; p != null; p = p.Parent)
            {
                stack.Add(p);
            }

            if (topdown)
            {
                stack.Reverse();
            }

            return(stack);
        }
예제 #8
0
        public List <EvalTemplateEvent> GetEvalTemplateEventStack(bool topdown)
        {
            List <EvalTemplateEvent> stack = new List <EvalTemplateEvent>();

            for (TemplateFrame p = this; p != null; p = p.Parent)
            {
                EvalTemplateEvent eval = (EvalTemplateEvent)p.GetDebugState().Events[p.GetDebugState().Events.Count - 1];
                stack.Add(eval);
            }

            if (topdown)
            {
                stack.Reverse();
            }

            return(stack);
        }
예제 #9
0
        public List <Template> GetEnclosingInstanceStack(bool topdown)
        {
            List <Template> stack = new List <Template>();
            TemplateFrame   p     = this;

            while (p != null)
            {
                if (topdown)
                {
                    stack.Insert(0, p.Template);
                }
                else
                {
                    stack.Add(p.Template);
                }

                p = p.Parent;
            }
            return(stack);
        }
예제 #10
0
        /** Return a list with the same elements as v but in reverse order. null
         *  values are NOT stripped out. use Reverse(Strip(v)) to do that.
         */
        public virtual object Reverse(TemplateFrame frame, object v)
        {
            if (v == null)
                return null;

            v = ConvertAnythingIteratableToIterator(frame, v);
            IEnumerator it = v as IEnumerator;
            if (it != null)
            {
                List<object> a = new List<object>();
                while (it.MoveNext())
                    a.Add(it.Current);

                a.Reverse();
                return a;
            }

            return v;
        }
예제 #11
0
        /** Return the last attribute if multiple valued or the attribute
         *  itself if single-valued. Unless it's a list or array, this is pretty
         *  slow as it iterates until the last element.
         */
        public virtual object Last(TemplateFrame frame, object v)
        {
            if (v == null)
                return null;

            IList list = v as IList;
            if (list != null)
                return list[list.Count - 1];

            object last = v;
            v = ConvertAnythingIteratableToIterator(frame, v);
            IEnumerator it = v as IEnumerator;
            if (it != null)
            {
                while (it.MoveNext())
                    last = it.Current;
            }

            return last;
        }
예제 #12
0
        /** Return everything but the first attribute if multiple valued
         *  or null if single-valued.
         */
        public virtual object Rest(TemplateFrame frame, object v)
        {
            if (v == null)
                return null;

            v = ConvertAnythingIteratableToIterator(frame, v);
            IEnumerator it = v as IEnumerator;
            if (it != null)
            {
                if (!it.MoveNext())
                    return null; // if not even one value return null

                List<object> a = new List<object>();
                // first value is ignored above

                while (it.MoveNext())
                {
                    object o = it.Current;
                    a.Add(o);
                }

                return a;
            }

            // rest of single-valued attribute is null
            return null;
        }
예제 #13
0
 protected virtual void AddToList(List<object> list, TemplateFrame frame, object o)
 {
     o = Interpreter.ConvertAnythingIteratableToIterator(frame, o);
     if (o is IEnumerator)
     {
         // copy of elements into our temp list
         IEnumerator it = (IEnumerator)o;
         while (it.MoveNext())
             list.Add(it.Current);
     }
     else
     {
         list.Add(o);
     }
 }
예제 #14
0
 /** For every event, we track in overall list and in self's
  *  event list so that each template has a list of events used to
  *  create it.  If EvalTemplateEvent, store in parent's
  *  childEvalTemplateEvents list for STViz tree view.
  */
 protected void TrackDebugEvent(TemplateFrame frame, InterpEvent e)
 {
     //		System.out.println(e);
     this.events.Add(e);
     //		if ( self.debugState==null ) self.debugState = new ST.DebugState();
     //		self.debugState.events.add(e);
     frame.GetDebugState().Events.Add(e);
     if (e is EvalTemplateEvent)
     {
         //ST parent = getDebugState(self).interpEnclosingInstance;
         TemplateFrame parent = frame.Parent;
         if (parent != null)
         {
             // System.out.println("add eval "+e.self.getName()+" to children of "+parent.getName());
             //				if ( parent.debugState==null ) parent.debugState = new ST.DebugState();
             //				parent.debugState.childEvalTemplateEvents.add((EvalTemplateEvent)e);
             parent.GetDebugState().ChildEvalTemplateEvents.Add((EvalTemplateEvent)e);
         }
     }
 }
예제 #15
0
        internal virtual void PassThrough(TemplateFrame frame, string templateName, IDictionary<string, object> attrs)
        {
            CompiledTemplate c = group.LookupTemplate(templateName);
            if (c == null)
                return; // will get error later
            if (c.FormalArguments == null)
                return;

            foreach (FormalArgument arg in c.FormalArguments)
            {
                // if not already set by user, set to value from outer scope
                if (!attrs.ContainsKey(arg.Name))
                {
                    //System.out.println("arg "+arg.name+" missing");
                    try
                    {
                        object o = GetAttribute(frame, arg.Name);
                        // If the attribute exists but there is no value and
                        // the formal argument has no default value, make it null.
                        if (o == Template.EmptyAttribute && arg.DefaultValueToken == null)
                        {
                            attrs[arg.Name] = null;
                        }
                        // Else, the attribute has an existing value, set arg.
                        else if (o != Template.EmptyAttribute)
                        {
                            attrs[arg.Name] = o;
                        }
                    }
                    catch (AttributeNotFoundException)
                    {
                        // if no such attribute exists for arg.name, set parameter
                        // if no default value
                        if (arg.DefaultValueToken == null)
                        {
                            _errorManager.RuntimeError(frame, ErrorType.NO_SUCH_ATTRIBUTE_PASS_THROUGH, arg.Name);
                            attrs[arg.Name] = null;
                        }
                    }
                }
            }
        }
예제 #16
0
        internal virtual void StoreArguments(TemplateFrame frame, int nargs, Template st)
        {
            if (nargs > 0 && !st.impl.HasFormalArgs && st.impl.FormalArguments == null)
            {
                st.Add(Template.ImplicitArgumentName, null); // pretend we have "it" arg
            }

            int nformalArgs = 0;
            if (st.impl.FormalArguments != null)
                nformalArgs = st.impl.FormalArguments.Count;
            int firstArg = sp - (nargs - 1);
            int numToStore = Math.Min(nargs, nformalArgs);
            if (st.impl.IsAnonSubtemplate)
                nformalArgs -= predefinedAnonSubtemplateAttributes.Length;

            if (nargs < (nformalArgs - st.impl.NumberOfArgsWithDefaultValues) ||
                 nargs > nformalArgs)
            {
                _errorManager.RuntimeError(frame,
                                    ErrorType.ARGUMENT_COUNT_MISMATCH,
                                    nargs,
                                    st.impl.Name,
                                    nformalArgs);
            }

            if (st.impl.FormalArguments == null)
                return;

            for (int i = 0; i < numToStore; i++)
            {
                object o = operands[firstArg + i];
                string argName = st.impl.FormalArguments[i].Name;
                st.RawSetAttribute(argName, o);
            }
        }
예제 #17
0
        // <names,phones:{n,p | ...}> or <a,b:t()>
        // todo: i, i0 not set unless mentioned? map:{k,v | ..}?
        protected virtual Template.AttributeList ZipMap(TemplateFrame frame, List<object> exprs, Template prototype)
        {
            Template self = frame.Template;

            if (exprs == null || prototype == null || exprs.Count == 0)
            {
                return null; // do not apply if missing templates or empty values
            }
            // make everything iterable
            for (int i = 0; i < exprs.Count; i++)
            {
                object attr = exprs[i];
                if (attr != null)
                    exprs[i] = ConvertAnythingToIterator(frame, attr);
            }

            // ensure arguments line up
            int numExprs = exprs.Count;
            CompiledTemplate code = prototype.impl;
            List<FormalArgument> formalArguments = code.FormalArguments;
            if (!code.HasFormalArgs || formalArguments == null)
            {
                _errorManager.RuntimeError(frame, ErrorType.MISSING_FORMAL_ARGUMENTS);
                return null;
            }

            // todo: track formal args not names for efficient filling of locals
            object[] formalArgumentNames = formalArguments.Select(i => i.Name).ToArray();
            int nformalArgs = formalArgumentNames.Length;
            if (prototype.IsAnonymousSubtemplate)
                nformalArgs -= predefinedAnonSubtemplateAttributes.Length;

            if (nformalArgs != numExprs)
            {
                _errorManager.RuntimeError(frame, ErrorType.MAP_ARGUMENT_COUNT_MISMATCH, numExprs, nformalArgs);
                // TODO just fill first n
                // truncate arg list to match smaller size
                int shorterSize = Math.Min(formalArgumentNames.Length, numExprs);
                numExprs = shorterSize;
                Array.Resize(ref formalArgumentNames, shorterSize);
            }

            // keep walking while at least one attribute has values

            Template.AttributeList results = new Template.AttributeList();
            int i2 = 0; // iteration number from 0
            while (true)
            {
                // get a value for each attribute in list; put into Template instance
                int numEmpty = 0;
                Template embedded = group.CreateStringTemplateInternally(prototype);
                embedded.RawSetAttribute("i0", i2);
                embedded.RawSetAttribute("i", i2 + 1);
                for (int a = 0; a < numExprs; a++)
                {
                    IEnumerator it = (IEnumerator)exprs[a];
                    if (it != null && it.MoveNext())
                    {
                        string argName = (string)formalArgumentNames[a];
                        object iteratedValue = it.Current;
                        embedded.RawSetAttribute(argName, iteratedValue);
                    }
                    else
                    {
                        numEmpty++;
                    }
                }

                if (numEmpty == numExprs)
                    break;

                results.Add(embedded);
                i2++;
            }
            return results;
        }
예제 #18
0
        public static object ConvertAnythingIteratableToIterator(TemplateFrame frame, object o)
        {
            if (o == null)
                return null;

            string str = o as string;
            if (str != null)
                return str;

            IDictionary dictionary = o as IDictionary;
            if (dictionary != null)
            {
                if (frame.Template.Group.IterateAcrossValues)
                    return dictionary.Values.GetEnumerator();

                return dictionary.Keys.GetEnumerator();
            }

            ICollection collection = o as ICollection;
            if (collection != null)
                return collection.GetEnumerator();

            IEnumerable enumerable = o as IEnumerable;
            if (enumerable != null)
                return enumerable.GetEnumerator();

            //// This code is implied in the last line
            //Iterator iterator = o as Iterator;
            //if ( iterator != null )
            //    return iterator;

            return o;
        }
예제 #19
0
        /** Write out an expression result that uses expression options.
         *  E.g., &lt;names; separator=", "&gt;
         */
        protected virtual int WriteObjectWithOptions(ITemplateWriter @out, TemplateFrame frame, object o, object[] options)
        {
            int start = @out.Index; // track char we're about to Write
            // precompute all option values (Render all the way to strings)
            string[] optionStrings = null;
            if (options != null)
            {
                optionStrings = new string[options.Length];
                for (int i = 0; i < Compiler.TemplateCompiler.NUM_OPTIONS; i++)
                {
                    optionStrings[i] = ToString(frame, options[i]);
                }
            }

            if (options != null && options[(int)RenderOption.Anchor] != null)
            {
                @out.PushAnchorPoint();
            }

            int n = WriteObject(@out, frame, o, optionStrings);

            if (options != null && options[(int)RenderOption.Anchor] != null)
            {
                @out.PopAnchorPoint();
            }

            if (_debug)
            {
                Interval templateLocation = frame.Template.impl.sourceMap[frame.InstructionPointer];
                EvalExprEvent e = new EvalExprEvent(frame, Interval.FromBounds(start, @out.Index), templateLocation);
                TrackDebugEvent(frame, e);
            }

            return n;
        }
예제 #20
0
        protected virtual int WritePlainObject(ITemplateWriter @out, TemplateFrame frame, object o, string[] options)
        {
            string formatString = null;
            if (options != null)
                formatString = options[(int)RenderOption.Format];
            IAttributeRenderer r = frame.Template.impl.NativeGroup.GetAttributeRenderer(o.GetType());

            string v;
            if (r != null)
            {
                v = r.ToString(o, formatString, culture);
            }
            else
            {
                if (o is bool)
                    v = (bool)o ? "true" : "false";
                else if (o is bool? && ((bool?)o).HasValue)
                    v = ((bool?)o).Value ? "true" : "false";
                else
                    v = o.ToString();
            }

            int n;
            if (options != null && options[(int)RenderOption.Wrap] != null)
            {
                n = @out.Write(v, options[(int)RenderOption.Wrap]);
            }
            else
            {
                n = @out.Write(v);
            }

            return n;
        }
예제 #21
0
        /** Write out an expression result that doesn't use expression options.
         *  E.g., &lt;name&gt;
         */
        protected virtual int WriteObjectNoOptions(ITemplateWriter @out, TemplateFrame frame, object o)
        {
            int start = @out.Index; // track char we're about to Write
            int n = WriteObject(@out, frame, o, null);
            if (_debug)
            {
                Interval templateLocation = frame.Template.impl.sourceMap[frame.InstructionPointer];
                EvalExprEvent e = new EvalExprEvent(frame, Interval.FromBounds(start, @out.Index), templateLocation);
                TrackDebugEvent(frame, e);
            }

            return n;
        }
예제 #22
0
        /** Generic method to emit text for an object. It differentiates
         *  between templates, iterable objects, and plain old Java objects (POJOs)
         */
        protected virtual int WriteObject(ITemplateWriter @out, TemplateFrame frame, object o, string[] options)
        {
            int n = 0;
            if (o == null)
            {
                if (options != null && options[(int)RenderOption.Null] != null)
                    o = options[(int)RenderOption.Null];
                else
                    return 0;
            }

            ITypeProxyFactory proxyFactory = frame.Template.Group.GetTypeProxyFactory(o.GetType());
            if (proxyFactory != null)
                o = proxyFactory.CreateProxy(frame, o);

            System.Diagnostics.Debug.Assert(!(o is TemplateFrame));
            Template template = o as Template;
            if (template != null)
            {
                frame = new TemplateFrame(template, frame);
                if (options != null && options[(int)RenderOption.Wrap] != null)
                {
                    // if we have a wrap string, then inform writer it
                    // might need to wrap
                    try
                    {
                        @out.WriteWrap(options[(int)RenderOption.Wrap]);
                    }
                    catch (IOException ioe)
                    {
                        _errorManager.IOError(template, ErrorType.WRITE_IO_ERROR, ioe);
                    }
                }
                n = Execute(@out, frame);
            }
            else
            {
                o = ConvertAnythingIteratableToIterator(frame, o); // normalize
                try
                {
                    if (o is IEnumerator)
                        n = WriteIterator(@out, frame, o, options);
                    else
                        n = WritePlainObject(@out, frame, o, options);
                }
                catch (IOException ioe)
                {
                    _errorManager.IOError(frame.Template, ErrorType.WRITE_IO_ERROR, ioe, o);
                }
            }

            return n;
        }
예제 #23
0
        protected virtual int WriteIterator(ITemplateWriter @out, TemplateFrame frame, object o, string[] options)
        {
            if (o == null)
                return 0;

            int n = 0;
            IEnumerator it = (IEnumerator)o;
            string separator = null;
            if (options != null)
                separator = options[(int)RenderOption.Separator];
            bool seenAValue = false;
            while (it.MoveNext())
            {
                object iterValue = it.Current;
                // Emit separator if we're beyond first value
                bool needSeparator = seenAValue &&
                    separator != null &&            // we have a separator and
                    (iterValue != null ||           // either we have a value
                        options[(int)RenderOption.Null] != null); // or no value but null option
                if (needSeparator)
                    n += @out.WriteSeparator(separator);
                int nw = WriteObject(@out, frame, iterValue, options);
                if (nw > 0)
                    seenAValue = true;
                n += nw;
            }
            return n;
        }
예제 #24
0
        /** Return a new list w/o null values. */
        public virtual object Strip(TemplateFrame frame, object v)
        {
            if (v == null)
                return null;

            v = ConvertAnythingIteratableToIterator(frame, v);
            if (v is IEnumerator)
            {
                List<object> a = new List<object>();
                IEnumerator it = (IEnumerator)v;
                while (it.MoveNext())
                {
                    object o = it.Current;
                    if (o != null)
                        a.Add(o);
                }

                return a;
            }

            return v; // Strip(x)==x when x single-valued attribute
        }
예제 #25
0
        protected virtual string ToString(TemplateFrame frame, object value)
        {
            if (value != null)
            {
                if (value.GetType() == typeof(string))
                    return (string)value;

                // if not string already, must evaluate it
                StringWriter sw = new StringWriter();
                /*
                            Interpreter interp = new Interpreter(group, new NoIndentWriter(sw), culture);
                            interp.WriteObjectNoOptions(self, value, -1, -1);
                            */

                if (_debug && !frame.GetDebugState().IsEarlyEval)
                {
                    frame = new TemplateFrame(frame.Template, frame);
                    frame.GetDebugState().IsEarlyEval = true;
                }

                WriteObjectNoOptions(new NoIndentWriter(sw), frame, value);

                return sw.ToString();
            }
            return null;
        }
예제 #26
0
        /** Return all but the last element.  Trunc(x)=null if x is single-valued. */
        public virtual object Trunc(TemplateFrame frame, object v)
        {
            if (v == null)
                return null;

            v = ConvertAnythingIteratableToIterator(frame, v);
            if (v is IEnumerator)
            {
                List<object> a = new List<object>();
                IEnumerator it = (IEnumerator)v;
                while (it.MoveNext())
                    a.Add(it.Current);

                // remove the last item
                a.RemoveAt(a.Count - 1);
                return a;
            }

            // Trunc(x)==null when x single-valued attribute
            return null;
        }
예제 #27
0
            public object CreateProxy(TemplateFrame frame, object obj)
            {
                if (frame.Template.Name == "dictionaryTemplate")
                    return obj;

                Template template = GetDictionaryRendererTemplate();
                template.Add("dict", obj);
                return template;
            }
예제 #28
0
        internal virtual void StoreArguments(TemplateFrame frame, IDictionary<string, object> attrs, Template st)
        {
            if (attrs != null && attrs.Count > 0 &&
                 !st.impl.HasFormalArgs && st.impl.FormalArguments == null)
            {
                st.Add(Template.ImplicitArgumentName, null); // pretend we have "it" arg
            }

            int nformalArgs = 0;
            if (st.impl.FormalArguments != null)
                nformalArgs = st.impl.FormalArguments.Count;
            int nargs = 0;
            if (attrs != null)
                nargs = attrs.Count;

            if (nargs < (nformalArgs - st.impl.NumberOfArgsWithDefaultValues) || nargs > nformalArgs)
            {
                _errorManager.RuntimeError(frame,
                                    ErrorType.ARGUMENT_COUNT_MISMATCH,
                                    nargs,
                                    st.impl.Name,
                                    nformalArgs);
            }

            foreach (string argName in attrs.Keys)
            {
                // don't let it throw an exception in RawSetAttribute
                if (st.impl.FormalArguments == null || !st.impl.FormalArguments.Exists(i => i.Name == argName))
                {
                    _errorManager.RuntimeError(frame, ErrorType.NO_SUCH_ATTRIBUTE, argName);
                    continue;
                }

                object o = attrs[argName];
                st.RawSetAttribute(argName, o);
            }
        }
예제 #29
0
        protected virtual void SetFirstArgument(TemplateFrame frame, Template st, object attr)
        {
            if (!st.impl.HasFormalArgs)
            {
                if (st.impl.FormalArguments == null)
                {
                    st.Add(Template.ImplicitArgumentName, attr);
                    return;
                }
                // else fall thru to set locals[0]
            }

            if (st.impl.FormalArguments == null)
            {
                _errorManager.RuntimeError(frame, ErrorType.ARGUMENT_COUNT_MISMATCH, 1, st.impl.Name, 0);
                return;
            }

            st.locals[0] = attr;
        }
예제 #30
0
        internal virtual void SuperNew(TemplateFrame frame, string name, IDictionary<string, object> attrs)
        {
            Template self = frame.Template;
            Template st = null;
            CompiledTemplate imported = self.impl.NativeGroup.LookupImportedTemplate(name);
            if (imported == null)
            {
                _errorManager.RuntimeError(frame, ErrorType.NO_IMPORTED_TEMPLATE, name);
                st = self.Group.CreateStringTemplateInternally(new CompiledTemplate());
            }
            else
            {
                st = imported.NativeGroup.CreateStringTemplateInternally(imported);
                st.Group = group;
            }

            // get n args and store into st's attr list
            StoreArguments(frame, attrs, st);
            operands[++sp] = st;
        }
예제 #31
0
        /** Find an attr via dynamic scoping up enclosing scope chain.
         *  If not found, look for a map.  So attributes sent in to a template
         *  override dictionary names.
         */
        public virtual object GetAttribute(TemplateFrame frame, string name)
        {
            TemplateFrame scope = frame;
            while (scope != null)
            {
                Template template = scope.Template;
                FormalArgument arg = template.impl.TryGetFormalArgument(name);
                if (arg != null)
                {
                    object o = template.locals[arg.Index];
                    return o;
                }
                scope = scope.Parent;
            }

            // got to root template and no definition, try dictionaries in group
            Template self = frame.Template;
            if (self.impl.NativeGroup.IsDictionary(name))
                return self.impl.NativeGroup.RawGetDictionary(name);

            // not found, report unknown attr
            throw new AttributeNotFoundException(frame, name);
        }
예제 #32
0
        protected virtual int ExecuteImpl(ITemplateWriter @out, TemplateFrame frame)
        {
            Template self = frame.Template;
            int start = @out.Index; // track char we're about to Write
            Bytecode prevOpcode = Bytecode.Invalid;
            int n = 0; // how many char we Write out
            int nargs;
            int nameIndex;
            int addr;
            string name;
            object o, left, right;
            Template st;
            object[] options;
            byte[] code = self.impl.instrs;        // which code block are we executing
            int ip = 0;
            while (ip < self.impl.codeSize)
            {
                if (trace || _debug)
                    Trace(frame, ip);

                Bytecode opcode = (Bytecode)code[ip];
                frame.InstructionPointer = ip;
                ip++; //jump to next instruction or first byte of operand
                switch (opcode)
                {
                case Bytecode.INSTR_LOAD_STR:
                    int strIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    operands[++sp] = self.impl.strings[strIndex];
                    break;

                case Bytecode.INSTR_LOAD_ATTR:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = self.impl.strings[nameIndex];
                    try
                    {
                        o = GetAttribute(frame, name);
                        if (o == Template.EmptyAttribute)
                            o = null;
                    }
                    catch (AttributeNotFoundException)
                    {
                        _errorManager.RuntimeError(frame, ErrorType.NO_SUCH_ATTRIBUTE, name);
                        o = null;
                    }
                    operands[++sp] = o;
                    break;

                case Bytecode.INSTR_LOAD_LOCAL:
                    int valueIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    o = self.locals[valueIndex];
                    if (o == Template.EmptyAttribute)
                        o = null;
                    operands[++sp] = o;
                    break;

                case Bytecode.INSTR_LOAD_PROP:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    o = operands[sp--];
                    name = self.impl.strings[nameIndex];
                    operands[++sp] = GetObjectProperty(frame, o, name);
                    break;

                case Bytecode.INSTR_LOAD_PROP_IND:
                    object propName = operands[sp--];
                    o = operands[sp];
                    operands[sp] = GetObjectProperty(frame, o, propName);
                    break;

                case Bytecode.INSTR_NEW:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = self.impl.strings[nameIndex];
                    nargs = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    // look up in original hierarchy not enclosing template (variable group)
                    // see TestSubtemplates.testEvalSTFromAnotherGroup()
                    st = self.Group.GetEmbeddedInstanceOf(frame, name);
                    // get n args and store into st's attr list
                    StoreArguments(frame, nargs, st);
                    sp -= nargs;
                    operands[++sp] = st;
                    break;

                case Bytecode.INSTR_NEW_IND:
                    nargs = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = (string)operands[sp - nargs];
                    st = self.Group.GetEmbeddedInstanceOf(frame, name);
                    StoreArguments(frame, nargs, st);
                    sp -= nargs;
                    sp--; // pop template name
                    operands[++sp] = st;
                    break;

                case Bytecode.INSTR_NEW_BOX_ARGS:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = self.impl.strings[nameIndex];
                    IDictionary<string, object> attrs = (IDictionary<string, object>)operands[sp--];
                    // look up in original hierarchy not enclosing template (variable group)
                    // see TestSubtemplates.testEvalSTFromAnotherGroup()
                    st = self.Group.GetEmbeddedInstanceOf(frame, name);
                    // get n args and store into st's attr list
                    StoreArguments(frame, attrs, st);
                    operands[++sp] = st;
                    break;

                case Bytecode.INSTR_SUPER_NEW:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = self.impl.strings[nameIndex];
                    nargs = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    SuperNew(frame, name, nargs);
                    break;

                case Bytecode.INSTR_SUPER_NEW_BOX_ARGS:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = self.impl.strings[nameIndex];
                    attrs = (IDictionary<string, object>)operands[sp--];
                    SuperNew(frame, name, attrs);
                    break;

                case Bytecode.INSTR_STORE_OPTION:
                    int optionIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    o = operands[sp--];    // value to store
                    options = (object[])operands[sp]; // get options
                    options[optionIndex] = o; // store value into options on stack
                    break;

                case Bytecode.INSTR_STORE_ARG:
                    nameIndex = GetShort(code, ip);
                    name = self.impl.strings[nameIndex];
                    ip += Instruction.OperandSizeInBytes;
                    o = operands[sp--];
                    attrs = (IDictionary<string, object>)operands[sp];
                    attrs[name] = o; // leave attrs on stack
                    break;

                case Bytecode.INSTR_WRITE:
                    o = operands[sp--];
                    int n1 = WriteObjectNoOptions(@out, frame, o);
                    n += n1;
                    nwline += n1;
                    break;

                case Bytecode.INSTR_WRITE_OPT:
                    options = (object[])operands[sp--]; // get options
                    o = operands[sp--];                 // get option to Write
                    int n2 = WriteObjectWithOptions(@out, frame, o, options);
                    n += n2;
                    nwline += n2;
                    break;

                case Bytecode.INSTR_MAP:
                    st = (Template)operands[sp--]; // get prototype off stack
                    o = operands[sp--];		 // get object to map prototype across
                    Map(frame, o, st);
                    break;

                case Bytecode.INSTR_ROT_MAP:
                    int nmaps = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    List<Template> templates = new List<Template>();
                    for (int i = nmaps - 1; i >= 0; i--)
                        templates.Add((Template)operands[sp - i]);
                    sp -= nmaps;
                    o = operands[sp--];
                    if (o != null)
                        RotateMap(frame, o, templates);
                    break;

                case Bytecode.INSTR_ZIP_MAP:
                    st = (Template)operands[sp--];
                    nmaps = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    List<object> exprs = new List<object>();
                    for (int i = nmaps - 1; i >= 0; i--)
                        exprs.Add(operands[sp - i]);

                    sp -= nmaps;
                    operands[++sp] = ZipMap(frame, exprs, st);
                    break;

                case Bytecode.INSTR_BR:
                    ip = GetShort(code, ip);
                    break;

                case Bytecode.INSTR_BRF:
                    addr = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    o = operands[sp--]; // <if(expr)>...<endif>
                    if (!TestAttributeTrue(o))
                        ip = addr; // jump

                    break;

                case Bytecode.INSTR_OPTIONS:
                    operands[++sp] = new object[Compiler.TemplateCompiler.NUM_OPTIONS];
                    break;

                case Bytecode.INSTR_ARGS:
                    operands[++sp] = new Dictionary<string, object>();
                    break;

                case Bytecode.INSTR_PASSTHRU:
                    nameIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    name = self.impl.strings[nameIndex];
                    attrs = (IDictionary<string, object>)operands[sp];
                    PassThrough(frame, name, attrs);
                    break;

                case Bytecode.INSTR_LIST:
                    operands[++sp] = new List<object>();
                    break;

                case Bytecode.INSTR_ADD:
                    o = operands[sp--];             // pop value
                    List<object> list = (List<object>)operands[sp]; // don't pop list
                    AddToList(list, frame, o);
                    break;

                case Bytecode.INSTR_TOSTR:
                    // replace with string value; early eval
                    operands[sp] = ToString(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_FIRST:
                    operands[sp] = First(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_LAST:
                    operands[sp] = Last(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_REST:
                    operands[sp] = Rest(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_TRUNC:
                    operands[sp] = Trunc(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_STRIP:
                    operands[sp] = Strip(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_TRIM:
                    o = operands[sp--];
                    if (o.GetType() == typeof(string))
                    {
                        operands[++sp] = ((string)o).Trim();
                    }
                    else
                    {
                        _errorManager.RuntimeError(frame, ErrorType.EXPECTING_STRING, "trim", o.GetType());
                        operands[++sp] = o;
                    }
                    break;

                case Bytecode.INSTR_LENGTH:
                    operands[sp] = Length(operands[sp]);
                    break;

                case Bytecode.INSTR_STRLEN:
                    o = operands[sp--];
                    if (o.GetType() == typeof(string))
                    {
                        operands[++sp] = ((string)o).Length;
                    }
                    else
                    {
                        _errorManager.RuntimeError(frame, ErrorType.EXPECTING_STRING, "strlen", o.GetType());
                        operands[++sp] = 0;
                    }
                    break;

                case Bytecode.INSTR_REVERSE:
                    operands[sp] = Reverse(frame, operands[sp]);
                    break;

                case Bytecode.INSTR_NOT:
                    operands[sp] = !TestAttributeTrue(operands[sp]);
                    break;

                case Bytecode.INSTR_OR:
                    right = operands[sp--];
                    left = operands[sp--];
                    operands[++sp] = TestAttributeTrue(left) || TestAttributeTrue(right);
                    break;

                case Bytecode.INSTR_AND:
                    right = operands[sp--];
                    left = operands[sp--];
                    operands[++sp] = TestAttributeTrue(left) && TestAttributeTrue(right);
                    break;

                case Bytecode.INSTR_INDENT:
                    strIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    Indent(@out, frame, strIndex);
                    break;

                case Bytecode.INSTR_DEDENT:
                    @out.PopIndentation();
                    break;

                case Bytecode.INSTR_NEWLINE:
                    try
                    {
                        if (prevOpcode == Bytecode.INSTR_NEWLINE ||
                            prevOpcode == Bytecode.INSTR_INDENT ||
                            nwline > 0)
                        {
                            @out.Write(Environment.NewLine);
                        }
                        nwline = 0;
                    }
                    catch (IOException ioe)
                    {
                        _errorManager.IOError(self, ErrorType.WRITE_IO_ERROR, ioe);
                    }
                    break;

                case Bytecode.INSTR_NOOP:
                    break;

                case Bytecode.INSTR_POP:
                    sp--; // throw away top of stack
                    break;

                case Bytecode.INSTR_NULL:
                    operands[++sp] = null;
                    break;

                case Bytecode.INSTR_TRUE:
                    operands[++sp] = true;
                    break;

                case Bytecode.INSTR_FALSE:
                    operands[++sp] = false;
                    break;

                case Bytecode.INSTR_WRITE_STR:
                    strIndex = GetShort(code, ip);
                    ip += Instruction.OperandSizeInBytes;
                    o = self.impl.strings[strIndex];
                    n1 = WriteObjectNoOptions(@out, frame, o);
                    n += n1;
                    nwline += n1;
                    break;

                // TODO: generate this optimization
                //case Bytecode.INSTR_WRITE_LOCAL:
                //    valueIndex = GetShort(code, ip);
                //    ip += Instruction.OperandSizeInBytes;
                //    o = self.locals[valueIndex];
                //    if (o == Template.EmptyAttribute)
                //        o = null;

                //    n1 = WriteObjectNoOptions(@out, frame, o);
                //    n += n1;
                //    nwline += n1;
                //    break;

                default:
                    _errorManager.InternalError(self, "invalid bytecode @ " + (ip - 1) + ": " + opcode, null);
                    self.impl.Dump();
                    break;
                }

                prevOpcode = opcode;
            }

            if (_debug)
            {
                EvalTemplateEvent e = new EvalTemplateEvent(frame, Interval.FromBounds(start, @out.Index));
                TrackDebugEvent(frame, e);
            }
            return n;
        }
예제 #33
0
        protected virtual void Trace(TemplateFrame frame, int ip)
        {
            Template self = frame.Template;
            StringBuilder tr = new StringBuilder();
            BytecodeDisassembler dis = new BytecodeDisassembler(self.impl);
            StringBuilder buf = new StringBuilder();
            dis.DisassembleInstruction(buf, ip);
            string name = self.impl.Name + ":";
            if (object.ReferenceEquals(self.impl.Name, Template.UnknownName))
                name = string.Empty;

            tr.Append(string.Format("{0,-40}", name + buf));
            tr.Append("\tstack=[");
            for (int i = 0; i <= sp; i++)
            {
                object o = operands[i];
                PrintForTrace(tr, frame, o);
            }

            tr.Append(" ], calls=");
            tr.Append(frame.GetEnclosingInstanceStackString());
            tr.Append(", sp=" + sp + ", nw=" + nwline);
            string s = tr.ToString();

            if (_debug)
                executeTrace.Add(s);

            if (trace)
                Console.WriteLine(s);
        }
예제 #34
0
            public object CreateProxy(TemplateFrame frame, object obj)
            {
                Template template = obj as Template;
                if (template != null && template.Group != _ignoreGroup)
                    return new TemplateProxy(template);

                return obj;
            }
예제 #35
0
 /** Return the first attribute if multiple valued or the attribute
  *  itself if single-valued.  Used in &lt;names:First()&gt;
  */
 public virtual object First(TemplateFrame frame, object v)
 {
     if (v == null)
         return null;
     object r = v;
     v = ConvertAnythingIteratableToIterator(frame, v);
     if (v is IEnumerator)
     {
         IEnumerator it = (IEnumerator)v;
         if (it.MoveNext())
         {
             r = it.Current;
         }
     }
     return r;
 }
예제 #36
0
        public static IEnumerator ConvertAnythingToIterator(TemplateFrame frame, object o)
        {
            o = ConvertAnythingIteratableToIterator(frame, o);

            IEnumerator iter = o as IEnumerator;
            if (iter != null)
                return iter;

            Template.AttributeList singleton = new Template.AttributeList(1);
            singleton.Add(o);
            return singleton.GetEnumerator();
        }
예제 #37
0
        /** Execute template self and return how many characters it wrote to out */
        public virtual int Execute(ITemplateWriter @out, TemplateFrame frame)
        {
            try
            {
                if (frame.StackDepth > 200)
                    throw new TemplateException("Template stack overflow.", null);

                if (trace)
                    Console.Out.WriteLine("Execute({0})", frame.Template.Name);

                SetDefaultArguments(frame);
                return ExecuteImpl(@out, frame);
            }
            catch (Exception e)
            {
                if (e.IsCritical())
                {
                    e.PreserveStackTrace();
                    throw;
                }

                StringBuilder builder = new StringBuilder();
                builder.AppendLine(e.ToString());
                builder.AppendLine(e.StackTrace);
                _errorManager.RuntimeError(frame, ErrorType.INTERNAL_ERROR, "internal error: " + builder);
                return 0;
            }
        }