Cerata
A library to generate structural hardware designs
template.cc
1 // Copyright 2018-2019 Delft University of Technology
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "cerata/vhdl/template.h"
16 
17 #include <sstream>
18 #include <iostream>
19 #include "cerata/logging.h"
20 
21 namespace cerata::vhdl {
22 
23 Template::Template(std::istream *str) {
24  std::string line;
25  while (std::getline(*str, line)) {
26  lines_.push_back(line);
27  }
28  Analyze();
29 }
30 
31 Template Template::FromString(const std::string &str) {
32  std::stringstream stream;
33  stream << str;
34  Template result(&stream);
35  return result;
36 }
37 
38 Template Template::FromFile(const std::string &filename) {
39  std::ifstream ifs(filename);
40  if (!ifs.is_open()) {
41  CERATA_LOG(FATAL, "Could not open VHDL template file " + filename);
42  } else {
43  CERATA_LOG(DEBUG, "Opened template file " + filename);
44  }
45  Template result(&ifs);
46  ifs.close();
47  return result;
48 }
49 
50 void Template::Replace(const std::string &str, int with) {
51  Replace(str, std::to_string(with));
52 }
53 
54 void Template::Replace(const std::string &str, const std::string &with) {
55  if (replace_list_.find(str) != replace_list_.end()) {
56  for (const auto &loc : replace_list_[str]) {
57  // +3 for ${}
58  lines_[loc.line].replace(loc.start, str.length() + 3, with);
59  }
60  }
61 }
62 
63 std::string Template::ToString() {
64  std::string out;
65  for (const auto &l : lines_) {
66  out.append(l);
67  out.append("\n");
68  }
69  return out;
70 }
71 
73  // Replacement string regex
74  const std::regex rs_regex(R"(\$\{[a-zA-Z0-9_]+\})");
75 
76  // Empty the replace list
77  replace_list_ = {};
78 
79  // Analyze every line for replacement regex
80  size_t line_num = 0;
81  for (const auto &line : lines_) {
82  // Check if the line has any matches
83  auto rs_begin = std::sregex_iterator(line.begin(), line.end(), rs_regex);
84  auto rs_end = std::sregex_iterator();
85 
86  // Find the matches in this line
87  for (std::sregex_iterator i = rs_begin; i != rs_end; ++i) {
88  std::smatch match = *i;
89  std::string match_string = match.str();
90  std::string replace_string = match_string.substr(2, match_string.length() - 3);
91  trloc loc(trloc(line_num, static_cast<size_t>(match.position(0))));
92  replace_list_[replace_string].push_back(loc);
93  }
94 
95  line_num++;
96  }
97 }
98 
99 } // namespace cerata::vhdl
cerata::vhdl::Template
Class to hold and modify a VHDL template file.
Definition: template.h:36
cerata::vhdl::Template::Analyze
void Analyze()
Mark the locations of all replaceable template strings.
Definition: template.cc:72
cerata::vhdl::Template::ToString
std::string ToString()
Return the file as a string.
Definition: template.cc:63
cerata::vhdl::Template::FromString
static Template FromString(const std::string &str)
Construct a Template from an input string.
Definition: template.cc:31
cerata::vhdl::Template::FromFile
static Template FromFile(const std::string &filename)
Construct a Template from a file.
Definition: template.cc:38
cerata::vhdl::trloc
Structure to hold a template replacement string location.
Definition: template.h:26
cerata::stream
std::shared_ptr< Stream > stream(const std::string &name, const std::string &element_name, const std::shared_ptr< Type > &element_type, const std::vector< std::shared_ptr< Field >> &control)
Construct a new Stream type and return a shared pointer to it.
Definition: stream.cc:57
cerata::vhdl::Template::Template
Template(std::istream *str)
Construct a Template from an input stream.
Definition: template.cc:23
cerata::vhdl::Template::Replace
void Replace(const std::string &str, int with)
Replace a template replacement string with some number.
Definition: template.cc:50
cerata::vhdl
Contains everything related to the VHDL back-end.
Definition: architecture.cc:31