Documentation
Compiler Support
Since AdaYaml is written in Ada 2012, you can currently only use it in conjunction with the GNAT compiler; there are no other compilers available supporting Ada 2012. Since GNAT is the only viable compiler anyway, the AdaYaml source makes use of some GNAT-specific features.
Moreover, AdaYaml integrates with other tools of the GNAT environment, particularly the build system GPRbuild. You can easily define AdaYaml as dependency of your project using GPRbuild, and you can easily install AdaYaml on your system using GPRinstall. This is all described in detail in the GPRbuild documentation.
API Concepts
Memory Management
AdaYaml uses reference counting for managing resources allocated on the heap. Since reference counting makes it necessary to use smart pointers instead of raw access types, AdaYaml uses naming conventions derived from Rosen ‘95 to communicate the nature of these smart pointer types:
- A type named
Reference
or suffixed with_Reference
always is a reference to a reference-counted heap object. It is always a tagged type and always has a functionValue
which retrieves anAccessor
type to access the underlying object. TheAccessor
type is used to prevent deallocation and always has theImplicit_Dereference
aspect. Copying aReference
type always performs a shallow copy. - A type named
Instance
typically allocates its content on the stack (if used as a stack variable), but may contain references to heap values. If aReference
type exists wrapping anInstance
type, using theReference
type is generally optional. If a subroutine, particularly in another package, may take co-ownership of an instance, it will require aReference
as parameter type. - A type named
Pointer
is a raw access type to heap memory. A subroutine taking a value of such a type is guaranteed to take ownership of the value and deallocate it once it is not needed anymore.
The API has been designed so that a user does never need to actively deallocate anything, minimizing the danger of memory leaks.
Event Streams
Most parts of the API are concerned with either producing or consuming a stream of YAML events. A possible approach to make all consumers compatible with all producers would be to define a tagged base type that provides an abstract subroutine to query the next event from the stream. However, this would result in dispatching calls for every event query. Therefore, a different approach has been taken:
The API defines a package Yaml.Stream_Concept
which does not contain any
content other than generic parameters for a stream producer type, its reference,
and a subroutine querying the next event. Any type that can be used to
instantiate that package is considered an event stream producer. Basic packages
like Yaml.Parser
provide an instantiation of Stream_Concept
as child package
(Yaml.Parser.Stream
in this case).
Any package that either takes an instance of Stream_Concept
as generic
parameter itself or provides a generic subroutine taking such an instance is
considered an event stream consumer. So if you e.g. want to consume the event
stream generated by a parser, you instantiate your generic consumer with the
parameter Yaml.Parser.Stream
. A consumer provided by AdaYaml would be
Yaml.Presenter
with its generic subroutine Consume
.
Example
This example code reads a file (or stdin, if no file is given on the command line) and writes the resulting YAML events to stdout.