<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Scriptsprache: Wie Werte repraesentieren?]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>Ich bastle gerade an meiner eigenen kleinen Scriptsprache herum. Das Parsing klappt soweit erstmal, nur habe ich ein Problem beim ausfuehren. Und zwar weiss ich nicht, wie ich Werte moeglichst effizient repraesentieren kann. Im Moment habe ich dafuer boost.variant verwendet:</p>
<pre><code>struct Value
	{
		Value()                : type_(Type::VOID),   value_()  {}
		Value(String const&amp; s) : type_(Type::STRING), value_(s) {}
		Value(Char c)          : type_(Type::CHAR),   value_(c) {}
		Value(Int i)           : type_(Type::INT),    value_(i) {}
		Value(Float f)         : type_(Type::FLOAT),  value_(f) {}
		Value(Bool b)          : type_(Type::BOOL),   value_(b) {}

		Value&amp; operator = (String const&amp; s) { type_ = Type::STRING; value_ = s; return *this; }
		Value&amp; operator = (Char c)          { type_ = Type::CHAR;   value_ = c; return *this; }
		Value&amp; operator = (Int i)           { type_ = Type::INT;    value_ = i; return *this; }
		Value&amp; operator = (Float f)         { type_ = Type::FLOAT;  value_ = f; return *this; }
		Value&amp; operator = (Bool b)          { type_ = Type::BOOL;   value_ = b; return *this; }

		String const&amp; asString() const { return boost::get&lt;String&gt;(value_); }
		Char            asChar() const { return boost::get&lt;  Char&gt;(value_); }
		Int              asInt() const { return boost::get&lt;   Int&gt;(value_); }
		Float          asFloat() const { return boost::get&lt; Float&gt;(value_); }
		Bool            asBool() const { return boost::get&lt;  Bool&gt;(value_); }

		std::string toString() const;

		Type type() const { return type_; }
		bool initialized() const { return value_.which() != 0; }

	private:
		Type type_;
		boost::variant&lt;Void, String, Char, Int, Float, Bool&gt; value_;
	};
</code></pre>
<p>Das funktioniert mit eingebauten Typen noch gut. Jetzt will ich aber &quot;nullable&quot; Typen auch haben (aehnlich boost.optional), sowie Arrays, Funktionsreferenzen, Lambdas und Klassen. Und hier weiss ich nicht mehr weiter. Ich habe hier 2 verschiedene Welten: Wertypen und Referenztypen.</p>
<p>Ein aehnliches Problem habe ich bei Funktionen: Sie koennen verschiedene Rueckgabetypen haben und unterschiedliche Anzahl von Parametern. Im Moment repraesentiere ich Funktionen als std::function&lt;Value(std::vector&lt;Value&gt; const&amp;)&gt;, was unpraktisch ist, wenn man C++ Funktionen in der Scriptsprache verwenden moechte, da sie genau diese Signatur haben muessen. Z.B.:</p>
<pre><code>Value equalInt(std::vector&lt;Value&gt; const&amp; v)
		{
			return v[0].asInt() == v[1].asInt();
		}
</code></pre>
<p>Was hier auch noch voellig fehlt, ist die Information, ob ein Wert ein LValue oder RValue ist.</p>
<p>Habt ihr vielleicht Ideen, wie man das besser machen koennte?</p>
<p>Gruesse,<br />
Der Kellerautomat</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/316896/scriptsprache-wie-werte-repraesentieren</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Jul 2026 22:29:34 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/316896.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 20 May 2013 12:57:06 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Mon, 20 May 2013 13:00:09 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>Ich bastle gerade an meiner eigenen kleinen Scriptsprache herum. Das Parsing klappt soweit erstmal, nur habe ich ein Problem beim ausfuehren. Und zwar weiss ich nicht, wie ich Werte moeglichst effizient repraesentieren kann. Im Moment habe ich dafuer boost.variant verwendet:</p>
<pre><code>struct Value
	{
		Value()                : type_(Type::VOID),   value_()  {}
		Value(String const&amp; s) : type_(Type::STRING), value_(s) {}
		Value(Char c)          : type_(Type::CHAR),   value_(c) {}
		Value(Int i)           : type_(Type::INT),    value_(i) {}
		Value(Float f)         : type_(Type::FLOAT),  value_(f) {}
		Value(Bool b)          : type_(Type::BOOL),   value_(b) {}

		Value&amp; operator = (String const&amp; s) { type_ = Type::STRING; value_ = s; return *this; }
		Value&amp; operator = (Char c)          { type_ = Type::CHAR;   value_ = c; return *this; }
		Value&amp; operator = (Int i)           { type_ = Type::INT;    value_ = i; return *this; }
		Value&amp; operator = (Float f)         { type_ = Type::FLOAT;  value_ = f; return *this; }
		Value&amp; operator = (Bool b)          { type_ = Type::BOOL;   value_ = b; return *this; }

		String const&amp; asString() const { return boost::get&lt;String&gt;(value_); }
		Char            asChar() const { return boost::get&lt;  Char&gt;(value_); }
		Int              asInt() const { return boost::get&lt;   Int&gt;(value_); }
		Float          asFloat() const { return boost::get&lt; Float&gt;(value_); }
		Bool            asBool() const { return boost::get&lt;  Bool&gt;(value_); }

		std::string toString() const;

		Type type() const { return type_; }
		bool initialized() const { return value_.which() != 0; }

	private:
		Type type_;
		boost::variant&lt;Void, String, Char, Int, Float, Bool&gt; value_;
	};
</code></pre>
<p>Das funktioniert mit eingebauten Typen noch gut. Jetzt will ich aber &quot;nullable&quot; Typen auch haben (aehnlich boost.optional), sowie Arrays, Funktionsreferenzen, Lambdas und Klassen. Und hier weiss ich nicht mehr weiter. Ich habe hier 2 verschiedene Welten: Wertypen und Referenztypen.</p>
<p>Ein aehnliches Problem habe ich bei Funktionen: Sie koennen verschiedene Rueckgabetypen haben und unterschiedliche Anzahl von Parametern. Im Moment repraesentiere ich Funktionen als std::function&lt;Value(std::vector&lt;Value&gt; const&amp;)&gt;, was unpraktisch ist, wenn man C++ Funktionen in der Scriptsprache verwenden moechte, da sie genau diese Signatur haben muessen. Z.B.:</p>
<pre><code>Value equalInt(std::vector&lt;Value&gt; const&amp; v)
		{
			return v[0].asInt() == v[1].asInt();
		}
</code></pre>
<p>Was hier auch noch voellig fehlt, ist die Information, ob ein Wert ein LValue oder RValue ist.</p>
<p>Habt ihr vielleicht Ideen, wie man das besser machen koennte?</p>
<p>Gruesse,<br />
Der Kellerautomat</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2324696</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2324696</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Mon, 20 May 2013 13:00:09 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Mon, 20 May 2013 14:07:55 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Und zwar weiss ich nicht, wie ich Werte moeglichst effizient repraesentieren kann. Im Moment habe ich dafuer boost.variant verwendet:</p>
</blockquote>
<p>Warum speicherst du noch einmal den Typ? <code>variant</code> merkt sich den doch.<br />
String ist vermutlich deutlich größer als die anderen (Zahlen-)typen. Das verschwendet Speicher, wenn die meisten Values gar keine Strings sind.</p>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Das funktioniert mit eingebauten Typen noch gut. Jetzt will ich aber &quot;nullable&quot; Typen auch haben (aehnlich boost.optional)</p>
</blockquote>
<p>Ist das nicht Void?</p>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>sowie Arrays, Funktionsreferenzen, Lambdas und Klassen. Und hier weiss ich nicht mehr weiter. Ich habe hier 2 verschiedene Welten: Wertypen und Referenztypen.</p>
</blockquote>
<p>Führe eine abstrakte Klasse &quot;Object&quot; ein. Einer der möglichen Typen in Value ist dann <code>Object *</code> . Du hast vermutlich vor, einen Garbage Collector einzusetzen, also ist das mit dem Besitz der Objects kein Problem.<br />
String ist typischerweise von Object abgeleitet, ebenso Array, Closure, &quot;Klassen&quot; etc.</p>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Ein aehnliches Problem habe ich bei Funktionen: Sie koennen verschiedene Rueckgabetypen haben und unterschiedliche Anzahl von Parametern. Im Moment repraesentiere ich Funktionen als std::function&lt;Value(std::vector&lt;Value&gt; const&amp;)&gt;, was unpraktisch ist, wenn man C++ Funktionen in der Scriptsprache verwenden moechte, da sie genau diese Signatur haben muessen. Z.B.:</p>
<pre><code>Value equalInt(std::vector&lt;Value&gt; const&amp; v)
		{
			return v[0].asInt() == v[1].asInt();
		}
</code></pre>
</blockquote>
<p>Eine Idee:</p>
<pre><code class="language-cpp">struct Object
{
	virtual ~Object();
	virtual Value call(std::vector&lt;Value&gt; const &amp;arguments) const
	{
		throw std::runtime_error(&quot;Cannot call non-function&quot;);
	}
};

template &lt;class R, class ...Args&gt;
struct ExternalFunction : Object
{
	typedef std::function&lt;R (Args...)&gt; Function;

	template &lt;class F&gt;
	ExternalFunction(F &amp;&amp;args)
		: m_function{std::forward&lt;F&gt;(args)}
	{
	}

	virtual Value call(std::vector&lt;Value&gt; const &amp;arguments) const override
	{
		if (arguments.size() != sizeof...(Args))
		{
			throw std::runtime_error(&quot;...&quot;);
		}
		// irgendwelches kompliziertes Gefrickel
		// zum Konvertieren Value -&gt; Args, das mir jetzt nicht einfällt
		return toValue(m_function( ?? ));
	}

private:

	Function m_function;
};
</code></pre>
<p>Man kann natürlich die <code>std::function</code> noch wegbekommen ( `</p>
<p>template &lt;class R, class ...Args, class Functor&gt; struct ExternalFunction` ).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2324704</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2324704</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 20 May 2013 14:07:55 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 12:10:49 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Warum speicherst du noch einmal den Typ? <code>variant</code> merkt sich den doch.</p>
</blockquote>
<p>Da hast du wohl Recht, war mir bisher nicht so bewusst. Danke fuer den Hinweis!</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>String ist vermutlich deutlich größer als die anderen (Zahlen-)typen. Das verschwendet Speicher, wenn die meisten Values gar keine Strings sind.</p>
</blockquote>
<p>Auch das ist wohl wahr. Aber was besseres ist mir im Moment auch nicht eingefallen.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Das funktioniert mit eingebauten Typen noch gut. Jetzt will ich aber &quot;nullable&quot; Typen auch haben (aehnlich boost.optional)</p>
</blockquote>
<p>Ist das nicht Void?</p>
</blockquote>
<p>Nein. Void verwende ich als void-Rueckgabetyp, sowie fuer uninitialisierte Variablen.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>sowie Arrays, Funktionsreferenzen, Lambdas und Klassen. Und hier weiss ich nicht mehr weiter. Ich habe hier 2 verschiedene Welten: Wertypen und Referenztypen.</p>
</blockquote>
<p>Führe eine abstrakte Klasse &quot;Object&quot; ein. Einer der möglichen Typen in Value ist dann <code>Object *</code> . Du hast vermutlich vor, einen Garbage Collector einzusetzen, also ist das mit dem Besitz der Objects kein Problem.<br />
String ist typischerweise von Object abgeleitet, ebenso Array, Closure, &quot;Klassen&quot; etc.</p>
</blockquote>
<p>Genau das wollte ich eigentlich vermeiden. Diese &quot;Alles ist von Object abgeleitet&quot; hierarchien finde ich einfach falsch.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Ein aehnliches Problem habe ich bei Funktionen: Sie koennen verschiedene Rueckgabetypen haben und unterschiedliche Anzahl von Parametern. Im Moment repraesentiere ich Funktionen als std::function&lt;Value(std::vector&lt;Value&gt; const&amp;)&gt;, was unpraktisch ist, wenn man C++ Funktionen in der Scriptsprache verwenden moechte, da sie genau diese Signatur haben muessen. Z.B.:</p>
<pre><code>Value equalInt(std::vector&lt;Value&gt; const&amp; v)
		{
			return v[0].asInt() == v[1].asInt();
		}
</code></pre>
</blockquote>
<p>Eine Idee:</p>
<pre><code class="language-cpp">struct Object
{
	virtual ~Object();
	virtual Value call(std::vector&lt;Value&gt; const &amp;arguments) const
	{
		throw std::runtime_error(&quot;Cannot call non-function&quot;);
	}
};

template &lt;class R, class ...Args&gt;
struct ExternalFunction : Object
{
	typedef std::function&lt;R (Args...)&gt; Function;

	template &lt;class F&gt;
	ExternalFunction(F &amp;&amp;args)
		: m_function{std::forward&lt;F&gt;(args)}
	{
	}

	virtual Value call(std::vector&lt;Value&gt; const &amp;arguments) const override
	{
		if (arguments.size() != sizeof...(Args))
		{
			throw std::runtime_error(&quot;...&quot;);
		}
		// irgendwelches kompliziertes Gefrickel
		// zum Konvertieren Value -&gt; Args, das mir jetzt nicht einfällt
		return toValue(m_function( ?? ));
	}

private:

	Function m_function;
};
</code></pre>
<p>Man kann natürlich die <code>std::function</code> noch wegbekommen ( `</p>
<p>template &lt;class R, class ...Args, class Functor&gt; struct ExternalFunction` ).</p>
</blockquote>
<p>Die Sprache ist aber statisch typisiert, daher macht das so keinen Sinn. Zumal ich bezweifle, dass das besonders effizient ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325242</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325242</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 22 May 2013 12:10:49 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 12:25:01 GMT]]></title><description><![CDATA[<p>Hast du dir schon mal Implementationen anderer einfacher Skriptsprachen angesehen, beispielsweise TinyScheme oder Lua?</p>
<blockquote>
<p>das besonders effizient ist</p>
</blockquote>
<p>Du willst eine Scriptprache.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325246</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325246</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 22 May 2013 12:25:01 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 13:11:57 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Hast du dir schon mal Implementationen anderer einfacher Skriptsprachen angesehen, beispielsweise TinyScheme oder Lua?</p>
</blockquote>
<p>Nein um ehrlich zu sein. Lua fand ich schon immer haesslich.</p>
<p>knivil schrieb:</p>
<blockquote>
<blockquote>
<p>das besonders effizient ist</p>
</blockquote>
<p>Du willst eine Scriptprache.</p>
</blockquote>
<p>Na und? Alle mir bekannten Scriptsprachen sind saulahm...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325259</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325259</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 22 May 2013 13:11:57 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 13:22:49 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Na und? Alle mir bekannten Scriptsprachen sind saulahm...</p>
</blockquote>
<p>Damit meine ich, dass du dir ueber Effizienz keine Gedanken machen solltest, wenn es eine Scriptsprache sein soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325262</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325262</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Wed, 22 May 2013 13:22:49 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 13:32:21 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Die Sprache ist aber statisch typisiert, daher macht das so keinen Sinn.</p>
</blockquote>
<p>Für statisch typisiert brauchst du diese Value-Klasse doch gar nicht.</p>
<p>Wenn eine Funktion das erste mal ausgeführt wird (bzw. instanziiert, falls du Templates erlaubst) machst du Typchecking und kompilierst es in einen Zwischencode. Aus a+b wird <code>intAdd a b</code> , falls a und b Integer sind, <code>strConcat a b</code> falls es Strings sind etc. oder sonst TypError.</p>
<p>Wenn der Zwischencode ausgeführt wird, kann stillschweigend davon ausgegangen werden, dass die Typen stimmen, dann wird keine Value-Klasse benötigt.</p>
<p>Eine umfassende Value-Klasse und &quot;alles ist von Objekt abgeleitet&quot; sind mMn äquivalent und brauchst du genau dann, wenn du mit dynamischer Typisierung zu tun hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325267</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325267</guid><dc:creator><![CDATA[extendsobject]]></dc:creator><pubDate>Wed, 22 May 2013 13:32:21 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 15:38:37 GMT]]></title><description><![CDATA[<p>Mein Parser erzeugt mir einen Syntaxbaum, bei dem von Expression ablgeleitete Knoten eine virtuelle Methode evaluate(), sowie eine Methode type() haben, z.B.:</p>
<pre><code>struct LiteralExpression
{
    virtual Type type() const override
    {
        return value_.type();
    }

    virtual Value evaluate() const override
    {
        return value_;
    }

    Value value_;
};
</code></pre>
<p>Fuer bessere Vorschlaege bin ich natuerlich dankbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325308</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325308</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 22 May 2013 15:38:37 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Wed, 22 May 2013 18:23:48 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Mein Parser erzeugt mir einen Syntaxbaum, bei dem von Expression ablgeleitete Knoten eine virtuelle Methode evaluate(), sowie eine Methode type() haben</p>
</blockquote>
<p>Mehr Info über deine Sprache bitte.</p>
<p>Wozu brauchst du beim Ausführen den Syntaxbaum? In meiner Skriptsprache war ich auf den angewiesen wegen AST-Makros, aber sonst sehe ich dafür keinen Nutzen.</p>
<p>Wenn du eine statische Typisierung hast, kannst du Überladungen auflösen, Typen checken und komplexe Ausdrücke auf einfache umformen.</p>
<pre><code class="language-cpp">using variable_handle = int;
using function_handle = int;
struct expression {
  type t;
  union {
    struct assignment {
      variable_handle to; function_handle f; static_vector&lt;variable_handle&gt; args;
    };
    struct case { ... }; // if
    ...
}

// Der Code einer Funktion ist dann ein
std::vector&lt;expression&gt;
</code></pre>
<p>(auch funktionale Programmiersprachen können darauf reduziert werden, der Haskell-Interpreter/Compiler aus Glasgow macht das z.B.)</p>
<p>Lazy Evaluation ist kein hinreichender Grund für Syntaxbäume.</p>
<p>Du kannst es dir auch einfach machen und eine die statische Typisierung mit einer dynamischen zu simulieren. Dann passt dein Ansatz. Dann passe aber bitte deine Value-Klasse an und mach eine Klasse Object und lass Int/String/und so davon erben. Optional kann dann ebenfalls eine Unterklasse davon sein. Nur so kannst du übrigens int <code>optional&lt;optional&lt;int&gt; &gt;</code> repräsentieren, was für generischen Code nötig sein wird.</p>
<p>Vererbung heisst hier natürlich nicht virtual und override sondern schön von Hand mit einer Typ-ID, und einem CRTP-Visitor mit genau einem gigantischen switch-statement. Schonmal überlegt, wie du eigene Klassen unterstützen willst? Mit deinem Ansatz kommst du da nicht weit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325338</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325338</guid><dc:creator><![CDATA[extendsobject]]></dc:creator><pubDate>Wed, 22 May 2013 18:23:48 GMT</pubDate></item><item><title><![CDATA[Reply to Scriptsprache: Wie Werte repraesentieren? on Thu, 23 May 2013 10:40:33 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>knivil schrieb:</p>
<blockquote>
<p>Hast du dir schon mal Implementationen anderer einfacher Skriptsprachen angesehen, beispielsweise TinyScheme oder Lua?</p>
</blockquote>
<p>Nein um ehrlich zu sein.</p>
</blockquote>
<p>Dann tue es! Was schoen ist oder nicht, ist voellig belanglos. Hier gehts um Typrepreasentation und nicht um Sprache.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2325418</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2325418</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Thu, 23 May 2013 10:40:33 GMT</pubDate></item></channel></rss>