root / trunk / compiler / cppAst / ast / types / IntType.hpp @ 7
1 |
/**
|
---|---|
2 |
*
|
3 |
* OOAS Compiler - C++ AST
|
4 |
*
|
5 |
* Copyright 2015, AIT Austrian Institute of Technology.
|
6 |
* All rights reserved.
|
7 |
*
|
8 |
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
9 |
*
|
10 |
* If you modify the file please update the list of contributors below to in-
|
11 |
* clude your name. Please also stick to the coding convention of using TABs
|
12 |
* to do the basic (block-level) indentation and spaces for anything after
|
13 |
* that. (Enable the display of special chars and it should be pretty obvious
|
14 |
* what this means.) Also, remove all trailing whitespace.
|
15 |
*
|
16 |
* Contributors:
|
17 |
* Willibald Krenn (AIT)
|
18 |
* Stephan Zimmerer (AIT)
|
19 |
* Christoph Czurda (AIT)
|
20 |
*
|
21 |
*/
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
#pragma once
|
27 |
|
28 |
#include <cstdint> |
29 |
#include <ast/types/Type.hpp> |
30 |
#include <ast/IAstVisitor.hpp> |
31 |
#include <boost/format.hpp> |
32 |
#include <iostream> |
33 |
|
34 |
namespace Ast {
|
35 |
|
36 |
class IntType |
37 |
: public Type
|
38 |
{ |
39 |
protected:
|
40 |
std::int64_t m_low; |
41 |
std::int64_t m_high; |
42 |
|
43 |
IntType(): Type(TypeKind::IntType), m_low (0), m_high(0) {} |
44 |
|
45 |
IntType(const IntType& toCopy):
|
46 |
Type(toCopy), |
47 |
m_low (toCopy.m_low), |
48 |
m_high(toCopy.m_high) |
49 |
{} |
50 |
static IntType* create() {return new IntType();} |
51 |
static IntType* createCopy(const IntType& toCopy) {return new IntType(toCopy);} |
52 |
public:
|
53 |
friend class Ast; |
54 |
friend class Type; |
55 |
|
56 |
void init(TypeIdentifier* id, bool anonymousType, std::int64_t low, std::int64_t high) |
57 |
{ |
58 |
Type::init(id,anonymousType); |
59 |
m_low = low; |
60 |
m_high = high; |
61 |
} |
62 |
|
63 |
int64_t rangeLow() const {return m_low;}; |
64 |
int64_t rangeHigh() const {return m_high;}; |
65 |
|
66 |
void accept(IAstVisitor& visitor) override {visitor.visit(this);}; |
67 |
|
68 |
static bool firstTypeLessRange(IntType* first, IntType* second) { |
69 |
return first->m_low > second->m_low || first->m_high < second->m_high;
|
70 |
} |
71 |
|
72 |
bool isSigned() override {return m_low < 0;} |
73 |
|
74 |
uint32_t bitwidth() override {
|
75 |
if (m_low == INT64_MIN || m_high == INT64_MAX)
|
76 |
return 64; |
77 |
|
78 |
std::uint32_t result = 0;
|
79 |
if (m_low < 0 && m_high > 0) { |
80 |
std::uint32_t bitsforlow = (std::uint32_t) std::floor(std::log2(std::abs(m_low))) + 1;
|
81 |
std::uint32_t bitsforhigh = (std::uint32_t) std::floor(std::log2(std::abs(m_high))) + 1;
|
82 |
if (bitsforlow <= bitsforhigh)
|
83 |
result = bitsforhigh + 1; // we need one additional bit to represent the negative numbers |
84 |
else
|
85 |
result = bitsforlow; // positive values are included
|
86 |
} else {
|
87 |
std::uint64_t maxAbs = (std::uint64_t) std::max(std::abs(m_low), std::abs(m_high)); |
88 |
result = (std::uint32_t) std::floor(std::log2(maxAbs)) + 1;
|
89 |
} |
90 |
|
91 |
// check the result!
|
92 |
if (isSigned()) {
|
93 |
std::int64_t maxVal = (std::int64_t)(((std::uint64_t)1 << result) - 1); |
94 |
std::int64_t minVal = (std::int64_t)(((std::uint64_t)-1 << result));
|
95 |
if (maxVal < m_high) {
|
96 |
std::cout << " Error converting type (max wrong): "
|
97 |
<< " low: " << m_low
|
98 |
<< " high: " << m_high
|
99 |
<< " bits: " << result
|
100 |
<< std::endl; |
101 |
abort(); |
102 |
} |
103 |
if (minVal > m_low) {
|
104 |
std::cout << " Error converting type (min wrong): "
|
105 |
<< " low: " << m_low
|
106 |
<< " high: " << m_high
|
107 |
<< " bits: " << result
|
108 |
<< std::endl; |
109 |
abort(); |
110 |
} |
111 |
} else {
|
112 |
std::uint64_t maxVal = (((std::uint64_t)1 << result)-1); |
113 |
if (maxVal < (std::uint64_t)m_high) {
|
114 |
std::cout << " Error converting unsigned type (max wrong): "
|
115 |
<< " low: " << m_low
|
116 |
<< " high: " << m_high
|
117 |
<< " bits: " << result
|
118 |
<< std::endl; |
119 |
abort(); |
120 |
} |
121 |
} |
122 |
// std::cout << " Mapping int type " << toString() << ": "
|
123 |
// << " low: " << m_low
|
124 |
// << " high: " << m_high
|
125 |
// << " bits: " << result
|
126 |
// << std::endl;
|
127 |
|
128 |
return result;
|
129 |
} |
130 |
}; |
131 |
} |