<chapter>
  <title>Nix Language Reference</title>

  <sect1>
    <title>Grammar</title>

    <productionset>
      <title>Expressions</title>
      
      <production id="nix.expr">
        <lhs>Expr</lhs>
        <rhs>
          <nonterminal def="#nix.expr_function" />
        </rhs>
      </production>
      
      <production id="nix.expr_function">
        <lhs>ExprFunction</lhs>
        <rhs>
          '{' <nonterminal def="#nix.formals" /> '}' ':' <nonterminal def="#nix.expr_function" />
          <sbr />|
          <nonterminal def="#nix.expr_assert" />
        </rhs>
      </production>
      
      <production id="nix.expr_assert">
        <lhs>ExprAssert</lhs>
        <rhs>
          'assert' <nonterminal def="#nix.expr" /> ';' <nonterminal def="#nix.expr_assert" />
          <sbr />|
          <nonterminal def="#nix.expr_if" />
        </rhs>
      </production>
      
      <production id="nix.expr_if">
        <lhs>ExprIf</lhs>
        <rhs>
          'if' <nonterminal def="#nix.expr" /> 'then' <nonterminal def="#nix.expr" />
          'else' <nonterminal def="#nix.expr" />
          <sbr />|
          <nonterminal def="#nix.expr_op" />
        </rhs>
      </production>
      
      <production id="nix.expr_op">
        <lhs>ExprOp</lhs>
        <rhs>
          '!' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '==' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '!=' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '&amp;&amp;' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '||' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '->' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '//' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '~' <nonterminal def="#nix.expr_op" />
          <sbr />|
          <nonterminal def="#nix.expr_op" /> '?' <nonterminal def="#nix.id" />
          <sbr />|
          <nonterminal def="#nix.expr_app" />
        </rhs>
      </production>
      
      <production id="nix.expr_app">
        <lhs>ExprApp</lhs>
        <rhs>
          <nonterminal def="#nix.expr_app" /> '.' <nonterminal def="#nix.expr_select" />
          <sbr />|
          <nonterminal def="#nix.expr_select" />
        </rhs>
      </production>
      
      <production id="nix.expr_select">
        <lhs>ExprSelect</lhs>
        <rhs>
          <nonterminal def="#nix.expr_select" /> <nonterminal def="#nix.id" />
          <sbr />|
          <nonterminal def="#nix.expr_simple" />
        </rhs>
      </production>
      
      <production id="nix.expr_simple">
        <lhs>ExprSimple</lhs>
        <rhs>
          <nonterminal def="#nix.id" /> |
          <nonterminal def="#nix.int" /> |
          <nonterminal def="#nix.str" /> |
          <nonterminal def="#nix.path" /> |
          <nonterminal def="#nix.uri" />
          <sbr />|
          'true' | 'false' | 'null'
          <sbr />|
          '(' <nonterminal def="#nix.expr" /> ')'
          <sbr />|
          '{' <nonterminal def="#nix.bind" />* '}'
          <sbr />|
          'let' '{' <nonterminal def="#nix.bind" />* '}'
          <sbr />|
          'rec' '{' <nonterminal def="#nix.bind" />* '}'
          <sbr />|
          '[' <nonterminal def="#nix.expr_select" />* ']'
        </rhs>
      </production>

      <production id="nix.bind">
        <lhs>Bind</lhs>
        <rhs>
          <nonterminal def="#nix.id" /> '=' <nonterminal def="#nix.expr" /> ';'
          <sbr />|
          'inherit' ('(' <nonterminal def="#nix.expr" /> ')')? <nonterminal def="#nix.id" />* ';'
        </rhs>
      </production>

      <production id="nix.formals">
        <lhs>Formals</lhs>
        <rhs>
          <nonterminal def="#nix.formal" /> ',' <nonterminal def="#nix.formals" />
          | <nonterminal def="#nix.formal" />
        </rhs>
      </production>
          
      <production id="nix.formal">
        <lhs>Formal</lhs>
        <rhs>
          <nonterminal def="#nix.id" />
          <sbr />|
          <nonterminal def="#nix.id" /> '?' <nonterminal def="#nix.expr" />
        </rhs>
      </production>
          
    </productionset>

    <productionset>
      <title>Terminals</title>

      <production id="nix.id">
        <lhs>Id</lhs>
        <rhs>[a-zA-Z\_][a-zA-Z0-9\_\']*</rhs>
      </production>
    
      <production id="nix.int">
        <lhs>Int</lhs>
        <rhs>[0-9]+</rhs>
      </production>
    
      <production id="nix.str">
        <lhs>Str</lhs>
        <rhs>\"[^\n\"]*\"</rhs>
      </production>

      <production id="nix.path">
        <lhs>Path</lhs>
        <rhs>[a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+</rhs>
      </production>
    
      <production id="nix.uri">
        <lhs>Uri</lhs>
        <rhs>[a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&amp;\=\+\$\,\-\_\.\!\~\*\']+</rhs>
      </production>

      <production id="nix.ws">
        <lhs>Whitespace</lhs>
        <rhs>
          [ \t\n]+
          <sbr />|
          \#[^\n]*
          <sbr />|
          \/\*(.|\n)*\*\/
        </rhs>
      </production>

    </productionset>
    
  </sect1>
  


  <sect1>
    <title>Semantics</title>


    
    <sect2>
      <title>Built-in functions</title>

      <para>
        The Nix language provides the following built-in function
        (<quote>primops</quote>):
      </para>

      <variablelist>

        <varlistentry>
          <term><function>import</function>
          <replaceable>e</replaceable></term>
          <listitem>
            <para>
              Evaluates the expression <replaceable>e</replaceable>,
              which must yield a path value.  The Nix expression
              stored at this path in the file system is then read,
              parsed, and evaluated.  Returns the result of the
              evaluation of the Nix expression just read.
            </para>

            <para>
              Example: <literal>import ./foo.nix</literal> evaluates
              the expression stored in <filename>foo.nix</filename>
              (in the directory containing the expression in which the
              <function>import</function> occurs).
            </para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><function>derivation</function>
          <replaceable>e</replaceable></term>
          <listitem>
            <para>
              Evaluates the expression <replaceable>e</replaceable>,
              which must yield an attribute set.  [...]
            </para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><function>baseNameOf</function>
          <replaceable>e</replaceable></term>
          <listitem>
            <para>
              Evaluates the expression <replaceable>e</replaceable>,
              which must yield a string value, and returns a string
              representing its <emphasis>base name</emphasis>.  This
              is the substring following the last path separator
              (<literal>/</literal>).
            </para>

            <para>
              Example: <literal>baseNameOf "/foo/bar"</literal>
              returns <literal>"bar"</literal>, and
              <literal>baseNameOf "/foo/bar/"</literal> returns
              <literal>""</literal>.
            </para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><function>toString</function>
          <replaceable>e</replaceable></term>
          <listitem>
            <para>
              Evaluates the expression <replaceable>e</replaceable>
              and coerces it into a string, if possible.  Only
              strings, paths, and URIs can be so coerced.
            </para>

            <para>
              Example: <literal>toString
              http://www.cs.uu.nl/</literal> returns
              <literal>"http://www.cs.uu.nl/"</literal>.
            </para>
          </listitem>
        </varlistentry>
            
      </variablelist>

    </sect2>

  </sect1>
  

</chapter>