aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-dataloader/AbstractSyntaxTree.hpp
blob: ade1c8258d55a57a0522a4621f859a2c0cf9b21c (plain) (blame)
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once

#include <concepts>
#include <cstdio>
#include <string_view>
#include <utility>

#include <openvic-dataloader/NodeLocation.hpp>
#include <openvic-dataloader/detail/SymbolIntern.hpp>
#include <openvic-dataloader/detail/Utility.hpp>

#include <lexy/lexeme.hpp>

#include <dryad/node.hpp>
#include <dryad/node_map.hpp>
#include <dryad/symbol.hpp>
#include <dryad/tree.hpp>

#include <fmt/core.h>

#include <detail/InternalConcepts.hpp>

namespace ovdl {
   struct AbstractSyntaxTree : SymbolIntern {
      explicit AbstractSyntaxTree(std::size_t max_elements) : _symbol_interner(max_elements) {}

      symbol_type intern(const char* str, std::size_t length);
      symbol_type intern(std::string_view str);
      const char* intern_cstr(const char* str, std::size_t length);
      const char* intern_cstr(std::string_view str);
      symbol_interner_type& symbol_interner();
      const symbol_interner_type& symbol_interner() const;

      template<typename Reader>
      symbol_type intern(lexy::lexeme<Reader> lexeme) {
         return intern(lexeme.begin(), lexeme.size());
      }
      template<typename Reader>
      const char* intern_cstr(lexy::lexeme<Reader> lexeme) {
         return intern_cstr(lexeme.begin(), lexeme.size());
      }

   protected:
      symbol_interner_type _symbol_interner;
   };

   template<detail::IsFile FileT, std::derived_from<typename FileT::node_type> RootNodeT>
   struct BasicAbstractSyntaxTree : AbstractSyntaxTree {
      using file_type = FileT;
      using root_node_type = RootNodeT;
      using node_type = typename file_type::node_type;

      explicit BasicAbstractSyntaxTree(file_type&& file)
         : AbstractSyntaxTree(file.size()),
           _file { std::move(file) } {}

      template<typename Encoding, typename MemoryResource = void>
      explicit BasicAbstractSyntaxTree(lexy::buffer<Encoding, MemoryResource>&& buffer)
         : AbstractSyntaxTree(buffer.size()),
           _file { std::move(buffer) } {}

      void set_location(const node_type* n, NodeLocation loc) {
         _file.set_location(n, loc);
      }

      NodeLocation location_of(const node_type* n) const {
         return _file.location_of(n);
      }

      root_node_type* root() {
         return _tree.root();
      }

      const root_node_type* root() const {
         return _tree.root();
      }

      file_type& file() {
         return _file;
      }

      const file_type& file() const {
         return _file;
      }

      template<typename T, typename... Args>
      T* create(NodeLocation loc, Args&&... args) {
         auto node = _tree.template create<T>(DRYAD_FWD(args)...);
         set_location(node, loc);
         return node;
      }

      template<typename T, typename... Args>
      T* create(const char* begin, const char* end, Args&&... args) {
         return create<T>(NodeLocation::make_from(begin, end), DRYAD_FWD(args)...);
      }

      void set_root(root_node_type* node) {
         _tree.set_root(node);
      }

   protected:
      dryad::tree<root_node_type> _tree;
      file_type _file;
   };
}