Commits

Jason McKesson  committed 9d14758

Preliminary struct upgrades.

  • Participants
  • Parent commits 126ed83

Comments (0)

Files changed (2)

File docs/Structure_Reference.xml

         <para>When an action says, <quote>Provides access to the X parameter,</quote> this also
             means that the action <emphasis>cannot nest</emphasis> with any action that provides
             this parameter. Including itself.</para>
-        <glosslist>
-            <glossentry>
-                <glossterm>file</glossterm>
-                <glossdef>
-                    <para>Creates a tabbed-file. See the TabbedFile.lua module to understand what
-                        this is. The default function parameters are: <literal>(basename,
-                            options)</literal></para>
-                    <itemizedlist>
-                        <listitem>
-                            <para><literal>name</literal>: The exact name of a function to call that
-                                returns the full pathname of the file to create</para>
-                        </listitem>
-                    </itemizedlist>
-                    <para>Provides access to the <literal>hFile</literal> parameter.</para>
-                    <para>Note that you really need the <literal>basename</literal> variable. At the
-                        very least, you should extract the directory name from it, as you will need
-                        to attach that to the front of the return value from this function. You can
-                        use <literal>util.ParsePath</literal> for this. Thus, your code should look
-                        like:</para>
-                    <programlisting>function style_name.GetFilenameFunc(basename, ...)
+        <section>
+            <title>System</title>
+            <para>These actions are system-level actions. They can be used in any context, and they
+                don't have anything to do (directly at least) with writing data or even the spec
+                data at all.</para>
+            <glosslist>
+                <glossentry>
+                    <glossterm>group</glossterm>
+                    <glossdef>
+                        <para>Represents a collection of actions. This has no real semantics; it's
+                            mainly used as the base table for variables that contain actions. Every
+                            table in the structure must have an action, so this is used to group
+                            them. They can also have conditional attributes and such.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>filter</glossterm>
+                    <glossdef>
+                        <para>Will execute its child actions only if the given function returns
+                            true. The default parameters are <literal>()</literal> (ie:
+                            none).</para>
+                        <itemizedlist>
+                            <listitem>
+                                <para><literal>name</literal>: The base name of the function that
+                                    does filtering. The full name will be prefixed by
+                                            <quote><literal>Filter</literal></quote>.</para>
+                            </listitem>
+                            <listitem>
+                                <para><literal>neg</literal>: If this is true, then the meaning of
+                                    the return value is inverted. That is, if the function returns
+                                    true, then it will <emphasis>not</emphasis> process the
+                                    children. This is useful for reusing filter functions in
+                                    opposite ways without having to write a new one.</para>
+                            </listitem>
+                        </itemizedlist>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>context</glossterm>
+                    <glossdef>
+                        <para>Adds a user-defined value to the current context. This will create a
+                            new parameter within the scope of this action that any function can
+                            reference. The default parameter list is <literal>()</literal>.</para>
+                        <itemizedlist>
+                            <listitem>
+                                <para><literal>key</literal>: The string name of the new context
+                                    variable. Required.</para>
+                            </listitem>
+                            <listitem>
+                                <para><literal>data</literal>: A Lua value that represents the new
+                                    context variable's data.</para>
+                            </listitem>
+                            <listitem>
+                                <para><literal>name</literal>: The base name of the function to call
+                                    to fill in the context variable. The full name will be prefixed
+                                    by <quote><literal>State</literal></quote>.</para>
+                            </listitem>
+                            <listitem>
+                                <para><literal>dispose</literal>: The base name of a function that
+                                    takes the state (and <emphasis>only</emphasis> the context
+                                    variable, so no parameter selection). This will be called when
+                                    the variable is disposed of. This would be for clean-up work,
+                                    like for file closing and such. The full name will be prefixed
+                                    by <quote><literal>Dispose</literal></quote>.</para>
+                            </listitem>
+                        </itemizedlist>
+                        <para>Either <literal>name</literal> or <literal>data</literal> must be
+                            defined. <literal>data</literal> takes priority.</para>
+                        <para>The actual context variable created by this will be suffixed with the
+                                <literal>_</literal> character, to ensure that it does not conflict
+                            with system-defined context variables. Just as with other context
+                            variables, attempting to define the same one twice will result in an
+                            error.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>call</glossterm>
+                    <glossdef>
+                        <para>Calls a given function. The default parameter list is
+                                <literal>()</literal>.</para>
+                        <itemizedlist>
+                            <listitem>
+                                <para><literal>name</literal>: The name of the function to
+                                    call.</para>
+                            </listitem>
+                        </itemizedlist>
+                    </glossdef>
+                </glossentry>
+            </glosslist>
+        </section>
+        <section>
+            <title>File</title>
+            <para>These actions are for dealing with file data. Creating files, writing data to
+                files, etc.</para>
+            <glosslist>
+                <glossentry>
+                    <glossterm>file</glossterm>
+                    <glossdef>
+                        <para>Creates a tabbed-file. See the TabbedFile.lua module to understand
+                            what this is. The default function parameters are: <literal>(basename,
+                                options)</literal></para>
+                        <itemizedlist>
+                            <listitem>
+                                <para><literal>name</literal>: The exact name of a function to call
+                                    that returns the full pathname of the file to create</para>
+                            </listitem>
+                        </itemizedlist>
+                        <para>Provides access to the <literal>hFile</literal> parameter.</para>
+                        <para>Note that you really need the <literal>basename</literal> variable. At
+                            the very least, you should extract the directory name from it, as you
+                            will need to attach that to the front of the return value from this
+                            function. You can use <literal>util.ParsePath</literal> for this. Thus,
+                            your code should look like:</para>
+                        <programlisting>function style_name.GetFilenameFunc(basename, ...)
   local base, dir = util.ParsePath(basename)
   local filename = --compute filename here.
   return dir .. filename
 end</programlisting>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>block</glossterm>
-                <glossdef>
-                    <para>Writes the beginning of a block before executing its children, and writes
-                        the ending of a block after executing the children. The default function
-                        parameters are: <literal>(hFile, spec, options)</literal></para>
-                    <itemizedlist>
-                        <listitem>
-                            <para><literal>name</literal>: The base name of a pair of functions to
-                                call to write the beginning and end of the block. The block
-                                beginning function's name will be prefixed by
-                                        <quote><literal>WriteBlockBegin</literal></quote>; similarly
-                                the ending function is prefixed with
-                                        <quote><literal>WriteBlockEnd</literal></quote></para>
-                        </listitem>
-                    </itemizedlist>
-                    <para>Must be within the scope of <literal>hFile</literal>.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>group</glossterm>
-                <glossdef>
-                    <para>Represents a collection of actions. This has no real semantics; it's
-                        mainly used as the base table for variables that contain actions. Every
-                        table in the structure must have an action, so this is used to group them.
-                        They can also have conditional attributes and such.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>write</glossterm>
-                <glossdef>
-                    <para>Calls a function to write something to the file. The default parameters to
-                        the function are <literal>(hFile, specData, spec, options)</literal>.</para>
-                    <itemizedlist>
-                        <listitem>
-                            <para><literal>name</literal>: The base name of the function that does
-                                the actual writing. The full name will be prefixed by
-                                        <quote><literal>Write</literal></quote>.</para>
-                        </listitem>
-                    </itemizedlist>
-                    <para>Must be within the scope of <literal>hFile</literal>.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>blank</glossterm>
-                <glossdef>
-                    <para>Writes a blank line to the file.</para>
-                    <para>Must be within the scope of <literal>hFile</literal>.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>filter</glossterm>
-                <glossdef>
-                    <para>Will execute its child actions only if the given function returns true.
-                        The default parameters are <literal>(hFile, specData, spec,
-                            options)</literal>.</para>
-                    <itemizedlist>
-                        <listitem>
-                            <para><literal>name</literal>: The base name of the function that does
-                                filtering. The full name will be prefixed by
-                                        <quote><literal>Filter</literal></quote>.</para>
-                        </listitem>
-                        <listitem>
-                            <para><literal>neg</literal>: If this is true, then the meaning of the
-                                return value is inverted. That is, if the function returns true,
-                                then it will <emphasis>not</emphasis> process the children. This is
-                                useful for reusing filter functions in opposite ways without having
-                                to write a new one.</para>
-                        </listitem>
-                    </itemizedlist>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>ext-iter</glossterm>
-                <glossdef>
-                    <para>Executes its children once for every extension that the user explicitly
-                        asked to generate code for.</para>
-                    <para>Provides access to the <literal>extName</literal> parameter.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>version-iter</glossterm>
-                <glossdef>
-                    <para>Executes its children once for every version in the specification that is
-                        less than or equal to the one the user asked for. If we are processing a
-                        specification that doesn't have any versions (ie: isn't OpenGL), then none
-                        of the children will be executed.</para>
-                    <para>Provides access to the <literal>version</literal> parameter.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>sub-version-iter</glossterm>
-                <glossdef>
-                    <para>Execute its children once for every version less than or equal to the
-                        current <literal>version</literal> parameter.</para>
-                    <para>Must be within the scope of <literal>version</literal>. Provides access to
-                        the <literal>sub_version</literal> parameter.</para>
-                    <para>This is useful for generating a group of functions or files that do
-                        something for each version, and for each version of OpenGL &lt;= that
-                        version. For example, you can have a bunch of headers that only provide
-                        functions/enums for features introduced within that version. Then, you can
-                        generate a file for each version, which includes headers only for the
-                        contents of everything <emphasis>up to</emphasis> that version of OpenGL and
-                        not just within it.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>core-ext-iter</glossterm>
-                <glossdef>
-                    <para>Executes its children once for every core extension of the current
-                            <literal>version</literal> parameter. Note that this will iterate over
-                        the core extensions introduced in version <emphasis>only.</emphasis></para>
-                    <para>Must be within the scope of <literal>version</literal>. Provides access to
-                        the <literal>extName</literal> parameter.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>core-ext-cull-iter</glossterm>
-                <glossdef>
-                    <para>Executes its children once for every core extension of the current
-                            <literal>version</literal> parameter which <emphasis>was not
-                            requested</emphasis> by the user to be exported. That is, these are the
-                        extensions that you need to look at because they are core extensions (and
-                        thus part of the current version) and won't have looked at already as part
-                        of the regular extension iteration process.</para>
-                    <para>Must be within the scope of <literal>version</literal>. Provides access to
-                        the <literal>extName</literal> parameter.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>enum-iter</glossterm>
-                <glossdef>
-                    <para>Executes its children once for every enumerator within scope.
-                            <quote>Scope</quote> is defined by the <literal>extName</literal> and/or
-                            <literal>version</literal> parameters. If <literal>extName</literal> is
-                        available, then it will iterate over all enums in the extension. If
-                            <literal>version</literal> is available, then it will iterate over all
-                        enums that were introduced within that particular version (and
-                            <emphasis>only</emphasis> them). If both are available,
-                            <literal>extName</literal> takes priority.</para>
-                    <para>Must be within the scope of <literal>extName</literal> or
-                            <literal>version</literal>. Provides access to the
-                            <literal>enum</literal> and <literal>enumTable</literal>
-                        parameters.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>func-iter</glossterm>
-                <glossdef>
-                    <para>Executes its children once for every function within scope. Scope is
-                        defined as for <literal>enum-iter</literal>.</para>
-                    <para>Must be within the scope of <literal>extName</literal> or
-                            <literal>version</literal>. Provides access to the
-                            <literal>func</literal> and <literal>typemap</literal>
-                        parameters.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>enum-seen</glossterm>
-                <glossdef>
-                    <para>This is a special action which records which enumerators were iterated
-                        over within its scope. Every time an <literal>enum-iter</literal> finishes
-                        processing an enumerator, the enumerator name that was processed will be
-                        recorded in <literal>enumSeen</literal>. That allows the user to be able to
-                        detect if this is the first time (inside this scope) that the enum was
-                        processed. This helps styles execute statelessly.</para>
-                    <para>To see if an enumerator was processed already, use
-                            <literal>enumSeen[enum.name]</literal>. The value stored there will be a
-                        string containing the extension name or the version that it was most
-                        recently seen within.</para>
-                    <para>Provides access to the <literal>enumSeen</literal> parameter.</para>
-                    <para>Note that if you place a filter within an <literal>enum-iter</literal>
-                        block that is in an <literal>enum-seen</literal> scope, the filter's
-                        active/inactive status <emphasis>will not affect</emphasis> whether
-                            <literal>enumSeen</literal> will be updated. It doesn't matter if
-                        nothing was written; the enumerator being iterated over is enough.</para>
-                </glossdef>
-            </glossentry>
-            <glossentry>
-                <glossterm>func-seen</glossterm>
-                <glossdef>
-                    <para>Works like <literal>enum-seen</literal>, except for functions.</para>
-                    <para>Provides access to the <literal>funcSeen</literal> parameter.</para>
-                </glossdef>
-            </glossentry>
-        </glosslist>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>block</glossterm>
+                    <glossdef>
+                        <para>Writes the beginning of a block before executing its children, and
+                            writes the ending of a block after executing the children. The default
+                            function parameters are: <literal>(hFile, spec,
+                            options)</literal></para>
+                        <itemizedlist>
+                            <listitem>
+                                <para><literal>name</literal>: The base name of a pair of functions
+                                    to call to write the beginning and end of the block. The block
+                                    beginning function's name will be prefixed by
+                                            <quote><literal>WriteBlockBegin</literal></quote>;
+                                    similarly the ending function is prefixed with
+                                            <quote><literal>WriteBlockEnd</literal></quote></para>
+                            </listitem>
+                        </itemizedlist>
+                        <para>Must be within the scope of <literal>hFile</literal>.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>write</glossterm>
+                    <glossdef>
+                        <para>Calls a function to write something to the file. The default
+                            parameters to the function are <literal>(hFile, specData, spec,
+                                options)</literal>.</para>
+                        <itemizedlist>
+                            <listitem>
+                                <para><literal>name</literal>: The base name of the function that
+                                    does the actual writing. The full name will be prefixed by
+                                            <quote><literal>Write</literal></quote>.</para>
+                            </listitem>
+                        </itemizedlist>
+                        <para>Must be within the scope of <literal>hFile</literal>.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>blank</glossterm>
+                    <glossdef>
+                        <para>Writes a blank line to the file.</para>
+                        <para>Must be within the scope of <literal>hFile</literal>.</para>
+                    </glossdef>
+                </glossentry>
+            </glosslist>
+        </section>
+        <section>
+            <title>Iterators</title>
+            <para>These actions are for iterating over lists of data in the specification.</para>
+            <glosslist>
+                <glossentry>
+                    <glossterm>ext-iter</glossterm>
+                    <glossdef>
+                        <para>Executes its children once for every extension that the user
+                            explicitly asked to generate code for.</para>
+                        <para>Provides access to the <literal>extName</literal> parameter.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>version-iter</glossterm>
+                    <glossdef>
+                        <para>Executes its children once for every version in the specification that
+                            is less than or equal to the one the user asked for. If we are
+                            processing a specification that doesn't have any versions (ie: isn't
+                            OpenGL), then none of the children will be executed.</para>
+                        <para>Provides access to the <literal>version</literal> parameter.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>sub-version-iter</glossterm>
+                    <glossdef>
+                        <para>Execute its children once for every version less than or equal to the
+                            current <literal>version</literal> parameter.</para>
+                        <para>Must be within the scope of <literal>version</literal>. Provides
+                            access to the <literal>sub_version</literal> parameter.</para>
+                        <para>This is useful for generating a group of functions or files that do
+                            something for each version, and for each version of OpenGL &lt;= that
+                            version. For example, you can have a bunch of headers that only provide
+                            functions/enums for features introduced within that version. Then, you
+                            can generate a file for each version, which includes headers only for
+                            the contents of everything <emphasis>up to</emphasis> that version of
+                            OpenGL and not just within it.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>core-ext-iter</glossterm>
+                    <glossdef>
+                        <para>Executes its children once for every core extension of the current
+                                <literal>version</literal> parameter. Note that this will iterate
+                            over the core extensions introduced in version
+                                <emphasis>only.</emphasis></para>
+                        <para>Must be within the scope of <literal>version</literal>. Provides
+                            access to the <literal>extName</literal> parameter.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>core-ext-cull-iter</glossterm>
+                    <glossdef>
+                        <para>Executes its children once for every core extension of the current
+                                <literal>version</literal> parameter which <emphasis>was not
+                                requested</emphasis> by the user to be exported. That is, these are
+                            the extensions that you need to look at because they are core extensions
+                            (and thus part of the current version) and won't have looked at already
+                            as part of the regular extension iteration process.</para>
+                        <para>Must be within the scope of <literal>version</literal>. Provides
+                            access to the <literal>extName</literal> parameter.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>enum-iter</glossterm>
+                    <glossdef>
+                        <para>Executes its children once for every enumerator within scope.
+                                <quote>Scope</quote> is defined by the <literal>extName</literal>
+                            and/or <literal>version</literal> parameters. If
+                                <literal>extName</literal> is available, then it will iterate over
+                            all enums in the extension. If <literal>version</literal> is available,
+                            then it will iterate over all enums that were introduced within that
+                            particular version (and <emphasis>only</emphasis> them). If both are
+                            available, <literal>extName</literal> takes priority.</para>
+                        <para>Must be within the scope of <literal>extName</literal> or
+                                <literal>version</literal>. Provides access to the
+                                <literal>enum</literal> and <literal>enumTable</literal>
+                            parameters.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>func-iter</glossterm>
+                    <glossdef>
+                        <para>Executes its children once for every function within scope. Scope is
+                            defined as for <literal>enum-iter</literal>.</para>
+                        <para>Must be within the scope of <literal>extName</literal> or
+                                <literal>version</literal>. Provides access to the
+                                <literal>func</literal> and <literal>typemap</literal>
+                            parameters.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>enum-seen</glossterm>
+                    <glossdef>
+                        <para>This is a special action which records which enumerators were iterated
+                            over within its scope. Every time an <literal>enum-iter</literal>
+                            finishes processing an enumerator, the enumerator name that was
+                            processed will be recorded in <literal>enumSeen</literal>. That allows
+                            the user to be able to detect if this is the first time (inside this
+                            scope) that the enum was processed. This helps styles execute
+                            statelessly.</para>
+                        <para>To see if an enumerator was processed already, use
+                                <literal>enumSeen[enum.name]</literal>. The value stored there will
+                            be a string containing the extension name or the version that it was
+                            most recently seen within.</para>
+                        <para>Provides access to the <literal>enumSeen</literal> parameter.</para>
+                        <para>Note that if you place a filter within an <literal>enum-iter</literal>
+                            block that is in an <literal>enum-seen</literal> scope, the filter's
+                            active/inactive status <emphasis>will not affect</emphasis> whether
+                                <literal>enumSeen</literal> will be updated. It doesn't matter if
+                            nothing was written; the enumerator being iterated over is
+                            enough.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
+                    <glossterm>func-seen</glossterm>
+                    <glossdef>
+                        <para>Works like <literal>enum-seen</literal>, except for functions.</para>
+                        <para>Provides access to the <literal>funcSeen</literal> parameter.</para>
+                    </glossdef>
+                </glossentry>
+            </glosslist>
+        </section>
         <section>
             <title>Common Attributes</title>
-            <para>Here is a list of attributes that can be used in any action (or at least a lot of
-                them).</para>
+            <para>Actions can have attributes. What follows is a list of attributes that can be used
+                in any action (or at least in a lot of them).</para>
             <glosslist>
                 <glossentry>
                     <glossterm>name</glossterm>
                     </glossdef>
                 </glossentry>
                 <glossentry>
+                    <glossterm>value</glossterm>
+                    <glossdef>
+                        <para>If this is set, then the given Lua value will be passed to any
+                            functions called by this action as the <literal>value</literal>
+                            parameter. Note that this parameter is <emphasis>not
+                                inherited</emphasis>. This parameter is not given to any child
+                            actions; only the action this value is set on will have access to this
+                            value.</para>
+                    </glossdef>
+                </glossentry>
+                <glossentry>
                     <glossterm>cond</glossterm>
                     <glossdef>
                         <para>These are special conditionals that act like single-action filters.
                 </glossdef>
             </glossentry>
             <glossentry>
+                <glossterm>value</glossterm>
+                <glossdef>
+                    <para>A user-defined value. This parameter is only available if the action
+                        itself has the <literal>value</literal> attribute. Child actions of actions
+                        that have <literal>value</literal> attributes will <emphasis>not</emphasis>
+                        inherit them.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
                 <glossterm>hFile</glossterm>
                 <glossdef>
                     <para>A <literal>TabbedFile</literal>. This is a special kind of Lua IO file. It

File modules/Structure.lua

 local util = require "util"
 local TabbedFile = require "TabbedFile"
 
---[[
-Directory of used context names:
-
-- style
-- spec
-- specData
-- options
-- basename
-- hFile			Provided by file blocks
-- extName		Provided by extension iterators.
-- version		Provided by version iterators.
-- sub_version	Provided by sub-version iterators.
-- enum			Provided by enum iterators.
-- enumTable		Provided by enum iterators.
-- enumSeen		Provided by enum seen blocks.
-- func			Provided by function iterators.
-- typemap		Provided by function iterators.
-- funcSeen		Provided by func seen blocks.
-
-Structure actions:
-
-- file: Creates a TabbedFile.
--		name: The style function to call. It should return a filename. The defualt parameters are (basename, options)
-
-- block: Represents a block. Must be in a file scope.
--		name: Part of the function name to call. When starting the block, it will call "WriteBlockBegin"..name. To end it, it will call "WriteBlockEnd"..name. The default parameters are (hFile, spec, options).
-
-- group: Represents a collection of stuff. Has no particular semantics (though it can have conditionals and such).
-
-- write: Simply calls a given writing function. Must be in a file scope.
--		name: Part of the function name to call. The complete function name is "Write"..name. The default parameters are (hFile, specData, spec, options).
-
-- blank: Writes an empty line. Must be in a file scope.
-
-- filter: Contains a group of actions. If the named function returns false, then the children will not be processed.
--		name: Part of the function name to call. The complete function name is "Filter"..name. The default parameters are () (ie: none).
-
-- ext-iter: Iterates over all of the extensions explicitly requested by the user. Cannot nest. Children can access the `extName` parameter, the name of the current extension.
-
-- version-iter: Iterates over each version in the spec, which is less than or equal to the requested version, where applicable. Cannot nest. Children can access the `version` parameter, the current version as a *string*.
-
-- sub-version-iter: Iterates over each version that is less than or equal to the current version. Cannot nest. Must be done within a context that provides the `version` parameter. Children can access the `sub_version` parameter, the current sub-version as a *string*.
-
-- core-ext-iter: Iterates over all core extensions of the current version. Cannot nest. Must be done within a context that provides the `version` parameter. Children can access the `extName` parameter, the name of the current core extension.
-
-- core-ext-cull-iter: Iterates over all core extensions that were *not* explicitly asked for. Cannot nest. Must be done within a context that provides the `version` parameter. Children can access the `extName` parameter, the name of the current core extension.
-
-- enum-seen: Children can access the `enumSeen` parameter. This is a mapping between enumerator names and where that enumerator was first seen. If it is not in this list, then this enumerator was not processed before (within the scope of the `enum-seen`). The `enum-iter` works in tandem with this to keep the `enumSeen` table up-to-date. The value for an enum may be an extension name or a core version number.
-
-- enum-iter: Iterates over all of the enumerators within scope. The "scope" is defined by whether `extName` or `version` is available. So if `extName` is available, then it iterates over all enums within that extension. If `version` is available, then it iterates over enums within *just* that version (the options.profile also applies). If both are visible, `extName` wins. Children can access the `enum` and `enumTable` parameters, which are the current enum and a name-table of all enums in the system. The latter is used to determine the value of the enum.
-
-- func-seen: Children can access the `funcSeen` parameter. This works like `enum-seen` but for functions and `func-iter`.
-
-- func-iter: Iterates over all of the functions within scope, using the same scoping rules as `enum-iter`. Children can access the `func` and `typemap` parameters, which are the current function and a typemap used to compute parameters and return-values (primarily for C).
-
-Common properties:
-
-- name: The name of a function to call, or part of a name. This can also include a parenthesized list of parameters. The parameter names much match those in the above list of parameters, and those parameters must be available in this particular scope (different actions create different scopes. If a particular parameter is not available in a context, a runtime error will occur.
-
-- style: All `name`d functions must be within one of the tables in scope. The `style` command adds an additional scope of the given name. What this means is that the system will check each style within scope for a table with the given name. That table then becomes the most recent style scope that names are looked through. Thus, all names below this node (*including* this node's name) will search through this style and every previous style for their names.
-
-- optional: It is not an error for the `name`d function to be present. The action, and its children, will be processed as normal, ***except*** for `filter` actions. For them, if the function is not present, everything is filtered out; the children will not be processed.
-
-- first: When set, this particular action (and any of its child actions) will only be executed the first time through the most recent iteration loop. Note that this only works for the most recent iteration loop. And it only works within an interation loop, since they are the only ones who execute their children multiple times.
-
-- last: Like first, except for the last time through a block. Usually for inserting blank space.
-
-- cond: Only processes the node and its children if the condition is "true". Available conditions:
-	- ext-iter
-	- version-iter
-	- core-ext-iter
-	- core-ext-cull-iter
-	- enum-iter
-	- func-iter
-	- core-funcs: True if the spec has core functions. IE: is OpenGL.
-
-All of the iterator-based conditions will be true iff performing that iterator in this context would result in at least one match. They can only be used in the same context where the equivalent iterator could.
-
-]]
-
 local actionTypes = {}
 local conditionals = {}
 
 		end
 	end
 	
+	if(self.value) then
+		context.value = self.value
+	end
+	
 	local paramList = {}
 	for _, param in ipairs(self.params) do
 		assert(context[param], "The function " .. name ..
 		paramList[#paramList + 1] = context[param]
 	end
 	
-	return style[name](unpack(paramList))
+	local rets = { style[name](unpack(paramList)) }
+
+	if(self.value) then
+		context.value = nil
+	end
+
+	return unpack(rets)
 end
 
 function action:Assert(test, text)
 	
 	act.newStyle = data.style
 	act.optional = data.optional
+	act.value = data.value
 
 	--Make child actions recursively.
 	for _, child in ipairs(data) do
 end
 
 
+-------------------------------------
+-- Group Action
+local groupAction = {}
+
+MakeActionType("group", groupAction, function(self, data)
+end)
+
+
+-------------------------------------
+-- Call Action
+local callAction = {}
+
+function callAction:PreProcess(context)
+	self:CallFunction(context, self.name)
+end
+
+MakeActionType("call", callAction, function(self, data)
+	self.params = self.params or {}
+end)
+
+
+-------------------------------------
+-- Context Action
+local contextAction = {}
+
+function contextAction:PreProcess(context)
+	self:Assert(context[self.key] == nil,
+		"Attempt to nest the context variable " .. self.key)
+
+	if(self.data) then
+		context[self.key] = self.data
+	else
+		context[self.key] = self:CallFunction(context, self.name)
+	end
+end
+
+function contextAction:PostProcess(context)
+	local style = context:FindStyleForFunc(self.dispose)
+	self:Assert(style,
+		string.format("Could not find the disposal function %s for %s.",
+		self.dispose, self.key))
+		
+	style[self.dispose](context[self.key])
+	context[self.key] = nil
+end
+
+MakeActionType("context", contextAction, function(self, data)
+	assert(data.key, "Context actions must have a `key`")
+	self.key = data.key .. "_"
+	self.data = data.data
+	if(self.name) then
+		self.name = "State" .. self.name
+	end
+	self.dispose = data.dispose
+	if(self.dispose) then
+		self.dispose = "Dispose" .. self.dispose
+	end
+
+	assert(self.data or self.name, "Context actions must have either `data` or `name`.")
+
+	self.params = self.params or {}
+end)
+
+
+-------------------------------------------
+-- Filter Action
+local filterAction = {}
+
+function filterAction:PreProcess(context)
+	local shouldFilter = self:CallFunction(context, self.name)
+	if(self.neg) then
+		shouldFilter = not shouldFilter
+	end
+	return not shouldFilter
+end
+
+MakeActionType("filter", filterAction, function(self, data)
+	assert(data.name, "Filter actions must have a `name`")
+	self.name = "Filter" .. self.name
+	self.neg = data.neg
+	self.params = self.params or {}
+end)
+
+
 ----------------------------
 -- File Action
 local fileAction = {}
 
 function fileAction:PreProcess(context)
-	assert(context.hFile == nil, "You cannot nest `file` blocks.")
+	self:Assert(context.hFile == nil, "You cannot nest `file` blocks.")
 
 	local filename = self:CallFunction(context)
 	
 end)
 
 
--------------------------------------
--- Group Action
-local groupAction = {}
-
-MakeActionType("group", groupAction, function(self, data)
-end)
-
-
 ------------------------------------------
 -- Write Action
 local writeAction = {}
 end)
 
 
--------------------------------------------
--- Filter Action
-local filterAction = {}
-
-function filterAction:PreProcess(context)
-	local shouldFilter = self:CallFunction(context, self.name)
-	if(self.neg) then
-		shouldFilter = not shouldFilter
-	end
-	return not shouldFilter
-end
-
-MakeActionType("filter", filterAction, function(self, data)
-	assert(data.name, "Filter actions must have a `name`")
-	self.name = "Filter" .. self.name
-	self.neg = data.neg
-	self.params = self.params or {}
-end)
-
-
 ---------------------------------------------
 -- Extension Iterator Action
 local extIterAction = {}