summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/parse/metavar-map.hxx
blob: 7dc2bbce765a03eadfe47ed001d01ca1609fbbab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
 ** \file parse/metavar-map.hxx
 ** \brief Implementation of parse::MetavarMap.
 */

#pragma once

#include <sstream>
#include <string>

#include <misc/contract.hh>
#include <misc/indent.hh>
#include <parse/metavar-map.hh>

namespace parse
{
  template <typename Data>
  MetavarMap<Data>::MetavarMap(const std::string& name)
    : name_(name)
    , map_()
  {}

  template <typename Data> MetavarMap<Data>::~MetavarMap()
  {
    // At this point, every metavariable should have been taken from the map.
    assertion(map_.empty()) << *this << "not empty, aborting.\n";
  }

  template <typename Data>
  std::string MetavarMap<Data>::show(unsigned key) const
  {
    return '_' + name_ + '(' + std::to_string(key) + ')';
  }

  template <typename Data>
  std::ostream& MetavarMap<Data>::dump(std::ostream& ostr) const
  {
    ostr << "MetavarMap<" << name_ << "> = [";

    if (map_.empty())
      return ostr << " ]" << misc::iendl;

    ostr << misc::incindent;

    for (const auto& [k, v] : map_)
      ostr << misc::iendl << show(k) << " -> " << v;

    return ostr << misc::decendl << "]" << misc::iendl;
  }

  template <typename Data>
  std::string MetavarMap<Data>::append_(unsigned& count, Data* data)
  {
    map_[count] = data;
    return show(count++);
  }

  template <typename Data> Data* MetavarMap<Data>::take_(unsigned key)
  {
    return map_.take(key);
  }

  template <typename Data>
  std::ostream& operator<<(std::ostream& ostr, const MetavarMap<Data>& m)
  {
    return m.dump(ostr);
  }

} // namespace parse