Cerata
A library to generate structural hardware designs
type.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/type.h"
16 
17 #include <utility>
18 #include <string>
19 #include <iostream>
20 
21 #include "cerata/utils.h"
22 #include "cerata/node.h"
23 #include "cerata/flattype.h"
24 #include "cerata/pool.h"
25 
26 namespace cerata {
27 
28 bool Type::Is(Type::ID type_id) const {
29  return type_id == id_;
30 }
31 
32 Type::Type(std::string name, Type::ID id) : Named(std::move(name)), id_(id) {}
33 
34 std::string Type::ToString(bool show_meta, bool show_mappers) const {
35  std::string ret;
36  switch (id_) {
37  case BIT : ret = name() + ":Bit";
38  break;
39  case VECTOR : ret = name() + ":Vec";
40  break;
41  case INTEGER: ret = name() + ":Int";
42  break;
43  case STRING : ret = name() + ":Str";
44  break;
45  case BOOLEAN: ret = name() + ":Bo";
46  break;
47  case RECORD : ret = name() + ":Rec";
48  break;
49  default :throw std::runtime_error("Corrupted Type ID.");
50  }
51 
52  if (show_meta || show_mappers) {
53  ret += "[";
54  // Append metadata
55  ret += ::cerata::ToString(meta);
56  if (show_mappers && !mappers_.empty()) {
57  ret += " ";
58  }
59 
60  // Append mappers
61  if (show_mappers && !mappers_.empty()) {
62  ret += "mappers={";
63  size_t i = 0;
64  for (const auto &m : mappers_) {
65  ret += m->b()->ToString();
66  if (i != mappers_.size() - 1) {
67  ret += ", ";
68  }
69  i++;
70  }
71  ret += "}";
72  }
73  ret += "]";
74  }
75  return ret;
76 }
77 
78 std::vector<std::shared_ptr<TypeMapper>> Type::mappers() const {
79  return mappers_;
80 }
81 
82 void Type::AddMapper(const std::shared_ptr<TypeMapper> &mapper, bool remove_existing) {
83  Type *other = mapper->b();
84  // Check if a mapper doesn't already exists
85  if (GetMapper(other, false)) {
86  if (!remove_existing) {
87  CERATA_LOG(FATAL, "Mapper already exists to convert "
88  "from " + this->ToString(true, true) + " to " + other->ToString(true, true));
89  } else {
90  RemoveMappersTo(other);
91  }
92  }
93 
94  // Check if the supplied mapper does not convert from this type.
95  if (mapper->a() != this) {
96  CERATA_LOG(FATAL, "Type converter does not convert from " + name());
97  }
98 
99  // Add the converter to this Type
100  mappers_.push_back(mapper);
101 
102  // If the other type doesnt already have it, add the inverse map there as well.
103  if (!other->GetMapper(this)) {
104  other->AddMapper(mapper->Inverse());
105  }
106 }
107 
108 std::optional<std::shared_ptr<TypeMapper>> Type::GetMapper(const std::shared_ptr<Type> &other) {
109  return GetMapper(other.get());
110 }
111 
112 std::optional<std::shared_ptr<TypeMapper>> Type::GetMapper(Type *other, bool generate_implicit) {
113  // Search for an existing type mapper.
114  for (const auto &m : mappers_) {
115  if (m->CanConvert(this, other)) {
116  return m;
117  }
118  }
119 
120  if (generate_implicit) {
121  // Implicit type mappers maybe be generated in three cases:
122 
123  // If it's exactly the same type object,
124  if (other == this) {
125  // Generate a type mapper to itself using the TypeMapper constructor.
126  return TypeMapper::Make(this);
127  }
128 
129  // If there is an explicit function in this Type to generate a mapper:
130  if (CanGenerateMapper(*other)) {
131  // Generate, add and return the new mapper.
132  auto new_mapper = GenerateMapper(other);
133  this->AddMapper(new_mapper);
134  return new_mapper;
135  }
136 
137  // Or if its an "equal" type, where each flattened type is equal.
138  if (this->IsEqual(*other)) {
139  // Generate an implicit type mapping.
140  return TypeMapper::MakeImplicit(this, other);
141  }
142  }
143 
144  // There is no mapper
145  return {};
146 }
147 
149  int removed = 0;
150  for (auto m = mappers_.begin(); m < mappers_.end(); m++) {
151  if ((*m)->CanConvert(this, other)) {
152  mappers_.erase(m);
153  removed++;
154  }
155  }
156  return removed;
157 }
158 
159 bool Type::IsEqual(const Type &other) const {
160  return other.id() == id_;
161 }
162 
163 std::shared_ptr<Type> Type::operator()(std::vector<Node *> nodes) {
164  auto generics = GetGenerics();
165 
166  if (nodes.size() != generics.size()) {
167  CERATA_LOG(ERROR, "Type contains " + std::to_string(generics.size())
168  + " generics, but only " + std::to_string(nodes.size())
169  + " arguments were supplied.");
170  }
171 
172  NodeMap map;
173  for (size_t i = 0; i < generics.size(); i++) {
174  map[generics[i]] = nodes[i];
175  }
176 
177  return Copy(map);
178 }
179 
180 std::shared_ptr<Type> Type::operator()(const std::vector<std::shared_ptr<Node>> &nodes) {
181  return this->operator()(ToRawPointers(nodes));
182 }
183 
184 Vector::Vector(std::string name, const std::shared_ptr<Node> &width)
185  : Type(std::move(name), Type::VECTOR) {
186  // Sanity check the width generic node.
187  if (!(width->IsParameter() || width->IsLiteral() || width->IsExpression())) {
188  CERATA_LOG(FATAL, "Vector width can only be Parameter, Literal or Expression node.");
189  }
190  width_ = width;
191 }
192 
193 std::shared_ptr<Type> vector(const std::string &name, const std::shared_ptr<Node> &width) {
194  return std::make_shared<Vector>(name, width);
195 }
196 
197 std::shared_ptr<Type> vector(const std::shared_ptr<Node> &width) {
198  return std::make_shared<Vector>("Vec_" + width->ToString(), width);
199 }
200 
201 std::shared_ptr<Type> vector(unsigned int width) {
202  return vector("vec_" + std::to_string(width), intl(static_cast<int>(width)));
203 }
204 
205 std::shared_ptr<Type> vector(std::string name, unsigned int width) {
206  auto ret = vector(width);
207  ret->SetName(std::move(name));
208  return ret;
209 }
210 
211 std::optional<Node *> Vector::width() const {
212  return width_.get();
213 }
214 
215 bool Vector::IsEqual(const Type &other) const {
216  // Must also be a vector
217  if (other.Is(Type::VECTOR)) {
218  // Must both have a width
219  if (width_ && other.width()) {
220  // TODO(johanpel): implement proper width checking..
221  return true;
222  }
223  }
224  return false;
225 }
226 
227 std::vector<Node *> Vector::GetGenerics() const {
228  if (!width_->IsLiteral()) {
229  return {width_.get()};
230  } else {
231  return {};
232  }
233 }
234 
235 Type &Vector::SetWidth(std::shared_ptr<Node> width) {
236  width_ = std::move(width);
237  return *this;
238 }
239 
240 std::shared_ptr<Type> bit(const std::string &name) {
241  if (name == "bit") {
242  // Return a static bit for the default bit.
243  static std::shared_ptr<Type> result = std::make_shared<Bit>(name);
244  return result;
245  } else {
246  std::shared_ptr<Type> result = std::make_shared<Bit>(name);
247  return result;
248  }
249 }
250 
251 std::shared_ptr<Type> boolean() {
252  static std::shared_ptr<Type> result = std::make_shared<Boolean>("boolean");
253  return result;
254 }
255 
256 std::shared_ptr<Type> integer() {
257  static std::shared_ptr<Type> result = std::make_shared<Integer>("integer");
258  return result;
259 }
260 
261 std::shared_ptr<Type> string() {
262  static std::shared_ptr<Type> result = std::make_shared<String>("string");
263  return result;
264 }
265 
266 std::optional<Node *> Bit::width() const {
267  return rintl(1);
268 }
269 
270 Field::Field(std::string name, std::shared_ptr<Type> type, bool reverse, bool sep)
271  : Named(std::move(name)), type_(std::move(type)), reverse_(reverse), sep_(sep) {}
272 
273 std::shared_ptr<Field> field(const std::string &name, const std::shared_ptr<Type> &type, bool reverse, bool sep) {
274  return std::make_shared<Field>(name, type, reverse, sep);
275 }
276 
277 std::shared_ptr<Field> field(const std::shared_ptr<Type> &type, bool reverse, bool sep) {
278  return std::make_shared<Field>(type->name(), type, reverse, sep);
279 }
280 
281 std::shared_ptr<Field> NoSep(std::shared_ptr<Field> field) {
282  field->NoSep();
283  return field;
284 }
285 
286 Record &Record::AddField(const std::shared_ptr<Field> &field, std::optional<size_t> index) {
287  if (index) {
288  auto it = fields_.begin() + *index;
289  fields_.insert(it, field);
290  } else {
291  fields_.push_back(field);
292  }
293  return *this;
294 }
295 
296 Record::Record(std::string name, std::vector<std::shared_ptr<Field>> fields)
297  : Type(std::move(name), Type::RECORD), fields_(std::move(fields)) {
298  // Check for duplicate field names.
299  std::vector<std::string> names;
300  for (const auto &field : fields_) {
301  names.push_back(field->name());
302  }
303  if (Unique(names).size() != fields_.size()) {
304  CERATA_LOG(ERROR, "Record field names must be unique.");
305  }
306 }
307 
308 std::shared_ptr<Record> record(const std::string &name, const std::vector<std::shared_ptr<Field>> &fields) {
309  return std::make_shared<Record>(name, fields);
310 }
311 
312 std::shared_ptr<Record> record(const std::string &name) {
313  return record(name, std::vector<std::shared_ptr<Field>>());
314 }
315 
316 std::shared_ptr<Record> record(const std::vector<std::shared_ptr<Field>> &fields) {
317  return record(std::string(""), fields);
318 }
319 
320 std::shared_ptr<Record> record(const std::initializer_list<std::shared_ptr<Field>> &fields) {
321  return record(std::string(""), std::vector<std::shared_ptr<Field>>(fields.begin(), fields.end()));
322 }
323 
324 bool Record::IsEqual(const Type &other) const {
325  if (&other == this) {
326  return true;
327  }
328  // Must also be a record
329  if (!other.Is(Type::RECORD)) {
330  return false;
331  }
332  // Must have same number of fields
333  auto &other_record = dynamic_cast<const Record &>(other);
334  if (other_record.num_fields() != this->num_fields()) {
335  return false;
336  }
337  // Each field must also be of equal type
338  for (size_t i = 0; i < this->num_fields(); i++) {
339  auto a = this->at(i);
340  auto b = other_record.at(i);
341  if (a->reversed() != b->reversed()) {
342  return false;
343  }
344  if (!a->type()->IsEqual(*b->type())) {
345  return false;
346  }
347  }
348  // If we didn't return already, the Record Types are the same
349  return true;
350 }
351 
352 std::vector<Node *> Record::GetGenerics() const {
353  std::vector<Node *> result;
354  for (const auto &field : fields_) {
355  auto field_params = field->type()->GetGenerics();
356  result.insert(result.end(), field_params.begin(), field_params.end());
357  }
358  return result;
359 }
360 
361 std::vector<Type *> Record::GetNested() const {
362  std::vector<Type *> result;
363  for (const auto &field : fields_) {
364  // Push back the field type itself.
365  result.push_back(field->type().get());
366  // Push back any nested types.
367  auto nested = field->type()->GetNested();
368  result.insert(result.end(), nested.begin(), nested.end());
369  }
370  return result;
371 }
372 
373 bool Record::IsPhysical() const {
374  for (const auto &f : fields_) {
375  if (!f->type()->IsPhysical()) {
376  return false;
377  }
378  }
379  return true;
380 }
381 
382 bool Record::IsGeneric() const {
383  for (const auto &f : fields_) {
384  if (f->type()->IsGeneric()) {
385  return true;
386  }
387  }
388  return false;
389 }
390 
391 std::shared_ptr<Type> Bit::Copy(const NodeMap &rebinding) const {
392  std::shared_ptr<Type> result;
393  result = bit(name());
394 
395  result->meta = meta;
396 
397  for (const auto &mapper : mappers_) {
398  auto new_mapper = mapper->Make(result.get(), mapper->b());
399  new_mapper->SetMappingMatrix(mapper->map_matrix());
400  result->AddMapper(new_mapper);
401  }
402 
403  return result;
404 }
405 
406 std::shared_ptr<Type> Vector::Copy(const NodeMap &rebinding) const {
407  std::shared_ptr<Type> result;
408  std::optional<std::shared_ptr<Node>> new_width = width_;
409  if (rebinding.count(width_.get()) > 0) {
410  new_width = rebinding.at(width_.get())->shared_from_this();
411  }
412  result = vector(name(), *new_width);
413 
414  result->meta = meta;
415 
416  for (const auto &mapper : mappers_) {
417  auto new_mapper = mapper->Make(result.get(), mapper->b());
418  new_mapper->SetMappingMatrix(mapper->map_matrix());
419  result->AddMapper(new_mapper);
420  }
421 
422  return result;
423 }
424 
425 std::shared_ptr<Field> Field::Copy(const NodeMap &rebinding) const {
426  std::shared_ptr<Field> result;
427  auto type = type_;
428  if (type_->IsGeneric()) {
429  type = type_->Copy(rebinding);
430  }
431  result = field(name(), type, reverse_, sep_);
432  result->meta = meta;
433  return result;
434 }
435 
436 Field &Field::SetType(std::shared_ptr<Type> type) {
437  type_ = std::move(type);
438  return *this;
439 }
440 
441 std::shared_ptr<Field> Field::Reverse() {
442  reverse_ = true;
443  return shared_from_this();
444 }
445 
446 std::shared_ptr<Type> Record::Copy(const NodeMap &rebinding) const {
447  std::shared_ptr<Type> result;
448  std::vector<std::shared_ptr<Field>> fields;
449  for (const auto &f : fields_) {
450  fields.push_back(f->Copy(rebinding));
451  }
452  result = record(name(), fields);
453 
454  result->meta = meta;
455 
456  for (const auto &mapper : mappers_) {
457  auto new_mapper = mapper->Make(result.get(), mapper->b());
458  new_mapper->SetMappingMatrix(mapper->map_matrix());
459  result->AddMapper(new_mapper);
460  }
461 
462  return result;
463 }
464 
465 Field *Record::at(size_t i) const {
466  if (i > fields_.size()) {
467  CERATA_LOG(FATAL, "Field index out of bounds.");
468  }
469  return fields_[i].get();
470 }
471 
472 Field *Record::operator[](size_t i) const { return at(i); }
473 
474 bool Record::Has(const std::string &name) const {
475  for (const auto &field : fields_) {
476  if (field->name() == name) {
477  return true;
478  }
479  }
480  return false;
481 }
482 
483 Field *Record::at(const std::string &name) const {
484  for (auto &f : fields_) {
485  if (f->name() == name) {
486  return f.get();
487  }
488  }
489  CERATA_LOG(ERROR, "Field with name " + name + " does not exist on Record type " + this->name()
490  + " Must one of: " + ToStringFieldNames());
491 }
492 
493 Field *Record::operator[](const std::string &name) const { return at(name); }
494 
495 std::string Record::ToStringFieldNames() const {
496  std::stringstream ss;
497  for (const auto &f : fields_) {
498  ss << f->name();
499  if (f != fields_.back()) {
500  ss << ", ";
501  }
502  }
503  return ss.str();
504 }
505 
506 } // namespace cerata
cerata::Type::mappers
std::vector< std::shared_ptr< TypeMapper > > mappers() const
Return possible type mappers.
Definition: type.cc:78
cerata::Record::fields_
std::vector< std::shared_ptr< Field > > fields_
The fields of this Record.
Definition: type.h:339
cerata::Type::RECORD
@ RECORD
? | ? | Yes
Definition: type.h:77
cerata::Record::num_fields
size_t num_fields() const
Return the number of fields in this record.
Definition: type.h:324
cerata::field
std::shared_ptr< Field > field(const std::string &name, const std::shared_ptr< Type > &type, bool reverse, bool sep)
Create a new RecordField, and return a shared pointer to it.
Definition: type.cc:273
cerata::TypeMapper::Make
static std::shared_ptr< TypeMapper > Make(Type *a)
Construct a new TypeMapper from some type to itself, and return a smart pointer to it.
Definition: flattype.cc:277
cerata::Record::ToStringFieldNames
std::string ToStringFieldNames() const
Return the names of the fields as a comma separated string.
Definition: type.cc:495
cerata::Type::BOOLEAN
@ BOOLEAN
No | No | No.
Definition: type.h:75
cerata::Field::meta
std::unordered_map< std::string, std::string > meta
Metadata for back-end implementations.
Definition: type.h:275
cerata::Field::Field
Field(std::string name, std::shared_ptr< Type > type, bool reverse=false, bool sep=true)
RecordField constructor.
Definition: type.cc:270
cerata::Record::IsPhysical
bool IsPhysical() const override
Return true if the Type has an immediate physical representation, false otherwise.
Definition: type.cc:373
cerata::Field::Reverse
std::shared_ptr< Field > Reverse()
Reverse the direction of this field and return itself.
Definition: type.cc:441
cerata::NoSep
std::shared_ptr< Field > NoSep(std::shared_ptr< Field > field)
Convenience function to disable the separator for a record field.
Definition: type.cc:281
cerata::Field
A Record field.
Definition: type.h:256
cerata::Type::id_
ID id_
Type ID.
Definition: type.h:165
cerata::Type::IsEqual
virtual bool IsEqual(const Type &other) const
Determine if this Type is exactly equal to an other Type.
Definition: type.cc:159
cerata::ToRawPointers
std::vector< T * > ToRawPointers(const std::vector< std::shared_ptr< T >> &list)
Convert a list of shared pointers to raw pointers.
Definition: utils.h:125
cerata::Type
A Type.
Definition: type.h:63
cerata::Type::BIT
@ BIT
Yes | No | No.
Definition: type.h:70
cerata::Vector::width
std::optional< Node * > width() const override
Return a pointer to the node representing the width of this vector, if specified.
Definition: type.cc:211
cerata::Record::Record
Record(std::string name, std::vector< std::shared_ptr< Field >> fields={})
Record constructor.
Definition: type.cc:296
cerata::Record
A Record type containing zero or more fields.
Definition: type.h:301
cerata::Type::Type
Type(std::string name, ID id)
Type constructor.
Definition: type.cc:32
cerata
Contains every Cerata class, function, etc...
Definition: api.h:41
cerata::Record::operator[]
Field * operator[](size_t i) const
Return the field at index i contained by this record.
Definition: type.cc:472
cerata::Type::GetMapper
std::optional< std::shared_ptr< TypeMapper > > GetMapper(Type *other, bool generate_implicit=true)
Get a mapper to another type, if it exists. Generates one, if possible, when generate_implicit = true...
Definition: type.cc:112
cerata::Record::at
Field * at(const std::string &name) const
Return the field with a specific name.
Definition: type.cc:483
cerata::Vector::SetWidth
Type & SetWidth(std::shared_ptr< Node > width)
Set the width of this vector.
Definition: type.cc:235
cerata::Field::SetType
Field & SetType(std::shared_ptr< Type > type)
Change the type of this field.
Definition: type.cc:436
cerata::Type::CanGenerateMapper
virtual bool CanGenerateMapper(const Type &other) const
Check if a mapper can be generated to another specific type.
Definition: type.h:121
cerata::Type::meta
std::unordered_map< std::string, std::string > meta
KV storage for metadata of tools or specific backend implementations.
Definition: type.h:131
cerata::NodeMap
std::unordered_map< const Node *, Node * > NodeMap
A mapping from one object to another object, used in e.g. type generic rebinding.
Definition: node.h:135
cerata::Type::Is
bool Is(ID type_id) const
Return true if the Type ID is type_id, false otherwise.
Definition: type.cc:28
cerata::Type::id
ID id() const
Return the Type ID.
Definition: type.h:88
cerata::Type::RemoveMappersTo
int RemoveMappersTo(Type *other)
Remove all mappers to a specific type.
Definition: type.cc:148
cerata::Record::IsGeneric
bool IsGeneric() const override
Return true if the Type is a generic type.
Definition: type.cc:382
cerata::Named::name
std::string name() const
Return the name of the object.
Definition: utils.h:45
cerata::Type::ToString
std::string ToString(bool show_meta=false, bool show_mappers=false) const
Return the Type ID as a human-readable string.
Definition: type.cc:34
cerata::Record::GetGenerics
std::vector< Node * > GetGenerics() const override
Return all nodes that potentially parametrize the fields of this record.
Definition: type.cc:352
cerata::Vector::Vector
Vector(std::string name, const std::shared_ptr< Node > &width)
Vector constructor.
Definition: type.cc:184
cerata::Type::mappers_
std::vector< std::shared_ptr< TypeMapper > > mappers_
A list of mappers that can map this type to another type.
Definition: type.h:167
cerata::string
std::shared_ptr< Type > string()
Return a static string type.
Definition: type.cc:261
cerata::Type::STRING
@ STRING
No | No | No.
Definition: type.h:74
cerata::boolean
std::shared_ptr< Type > boolean()
Return a static boolean type.
Definition: type.cc:251
cerata::TypeMapper::MakeImplicit
static std::shared_ptr< TypeMapper > MakeImplicit(Type *a, Type *b)
Construct a new TypeMapper from some type to another type, and automatically determine the type mappi...
Definition: flattype.cc:160
cerata::intl
std::shared_ptr< Literal > intl(int64_t i)
Obtain a shared pointer to an integer literal from the default node pool.
Definition: pool.h:144
cerata::Type::AddMapper
void AddMapper(const std::shared_ptr< TypeMapper > &mapper, bool remove_existing=true)
Add a type mapper.
Definition: type.cc:82
cerata::Record::GetNested
std::vector< Type * > GetNested() const override
Obtain any nested types.
Definition: type.cc:361
cerata::Type::GenerateMapper
virtual std::shared_ptr< TypeMapper > GenerateMapper(Type *other)
Generate a new mapper to a specific other type. Should be checked with CanGenerateMapper first,...
Definition: type.h:123
cerata::Named
Convenience structure for anything that is named. Names are case-sensitive.
Definition: utils.h:40
cerata::Record::Has
bool Has(const std::string &name) const
Return true if record has field with name name.
Definition: type.cc:474
cerata::Type::width
virtual std::optional< Node * > width() const
Return the width of the type, if it is synthesizable.
Definition: type.h:106
cerata::Record::fields
std::vector< std::shared_ptr< Field > > fields() const
Return all fields contained by this record.
Definition: type.h:322
cerata::vector
std::shared_ptr< Type > vector(const std::string &name, const std::shared_ptr< Node > &width)
Create a new vector type, and return a shared pointer to it.
Definition: type.cc:193
cerata::Record::IsEqual
bool IsEqual(const Type &other) const override
Determine if this Type is exactly equal to an other Type.
Definition: type.cc:324
cerata::record
std::shared_ptr< Record > record(const std::string &name, const std::vector< std::shared_ptr< Field >> &fields)
Create a new Record type, and return a shared pointer to it.
Definition: type.cc:308
cerata::rintl
Literal * rintl(int64_t i)
Obtain a raw pointer to an integer literal from the default node pool.
Definition: pool.h:140
cerata::Record::AddField
Record & AddField(const std::shared_ptr< Field > &field, std::optional< size_t > index=std::nullopt)
Add a field to this Record.
Definition: type.cc:286
cerata::Field::Copy
std::shared_ptr< Field > Copy(const NodeMap &rebinding) const
Create a copy of the field.
Definition: type.cc:425
cerata::Type::operator()
std::shared_ptr< Type > operator()(std::vector< Node * > nodes)
Make a copy of the type, and rebind any type generic nodes in order of the GetGenerics call.
Definition: type.cc:163
cerata::Type::INTEGER
@ INTEGER
No | No | No.
Definition: type.h:73
cerata::Type::GetGenerics
virtual std::vector< Node * > GetGenerics() const
Obtain any nodes that this type uses as generics.
Definition: type.h:126
cerata::integer
std::shared_ptr< Type > integer()
Return a static integer type.
Definition: type.cc:256
cerata::Bit::width
std::optional< Node * > width() const override
Bit width returns integer literal 1.
Definition: type.cc:266
cerata::bit
std::shared_ptr< Type > bit(const std::string &name)
Return a static bit type.
Definition: type.cc:240
cerata::Field::type
std::shared_ptr< Type > type() const
Return the type of the RecordField.
Definition: type.h:263
cerata::Type::Copy
virtual std::shared_ptr< Type > Copy() const
Make a copy of the type without rebinding.
Definition: type.h:147
cerata::Type::VECTOR
@ VECTOR
Yes | Yes | No.
Definition: type.h:71
cerata::Vector::IsEqual
bool IsEqual(const Type &other) const override
Determine if this Type is exactly equal to an other Type.
Definition: type.cc:215
cerata::Vector::GetGenerics
std::vector< Node * > GetGenerics() const override
Returns the width parameter of this vector, if any. Otherwise an empty list;.
Definition: type.cc:227
cerata::Unique
std::vector< T > Unique(const std::vector< T > &vec)
Return a copy of a vector without any duplicates.
Definition: utils.h:165
cerata::Type::ID
ID
The Type ID. Used for convenient type checking.
Definition: type.h:69