=head1 License
    phi programming language
    Copyright (C) 2018  Spencer Tipping

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
=cut

package phi;

use strict;
use warnings;


=head2 General object-management stuff
The boring details like C<to_string> and C<clone> that are normally factored
into base classes. This is all minimal because we're hand-coding these methods
where they exist (normally a lot of this would be generated by metaclasses).
=cut

use phi::protocol clone =>
  qw/ clone /;

use phi::protocol stringable =>
  qw/ to_s /;

use phi::protocol joinable =>
  qw/ + /;

use phi::protocol eq =>
  qw/ == /;


=head2 Interpreter protocol
We need this defined up front because it gives us heap allocation, which is
required for basically everything else. It also gives us some useful diagnostic
methods like C<print_string> and C<pnl> ("print with newline"). C<assert> is
used by unit tests and has signature C<< (cond message) -> ()|die >>.

The interpreter provides a mutable map of globals that we can use to name stuff
we generate at bootup. This is convenient because not all values exist within
phi0; sometimes we'll want to use phi1's constructor machinery to get to an
endpoint rather than trying prop stuff up in phi0.
=cut

use phi::protocol interpreter =>
  qw/ heap_allocate
      map_heap
      heap_usage
      heap_size
      globals
      def
      global
      print_string_fd
      pnl
      pnl_err
      read
      die
      assert
      exit /;


1;
