forked from FlatAssembler/AECforWebAssembly
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitManipulations.cpp
113 lines (103 loc) · 4.03 KB
/
bitManipulations.cpp
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
107
108
109
110
111
112
113
/*
* No doubt one of the main reasons C++ is a popular language for compilers
* is that compilers sometimes (though much less than an average developer
* probably thinks) need to do bit manipulation. It's significantly
* easier to do complicated bit manipulation in C++ than in JavaScript.
*/
#include <ciso646> // Necessary for Microsoft C++ Compiler.
#include <cstdint> // Apparently, GCC started to require this with version 13.
#include <cstring> // Some compilers apparently require this for "memcpy".
#include <iostream>
#include <regex>
#include <sstream>
#pragma once
bool isHexadecimalNumber(std::string str) {
// std::regex("^(\\d|[a-f])+$"), some C++ compilers (GCC when targeting
// FreeDOS and CLANG when targeting Oracle Linux) produce wrong code for
// that regex.
if (!str.size())
return false;
for (unsigned i = 0; i < str.size(); i++)
if (!std::isdigit(str[i]) and !(str[i] >= 'a' and str[i] <= 'f'))
return false;
return true;
}
std::string
reverseOrderOfBytes(std::string hexadecimal) // Because the JavaScript Virtual
// Machine is little-endian
{
if (hexadecimal.size() % 2 != 0 || hexadecimal.size() < 2 ||
!isHexadecimalNumber(hexadecimal)) {
std::cerr << "Internal compiler error: Some part of the compiler has "
"attempted to reverse the bytes of \""
<< hexadecimal << "\", which doesn't make sense." << std::endl;
std::exit(1);
}
std::string result = "\"";
for (int i = hexadecimal.size() - 2; i >= 0; i -= 2)
result += "\\" + hexadecimal.substr(i, 2);
result += '"';
return result;
}
std::string getCharVectorRepresentationOfCharacter(uint8_t Character) {
std::stringstream stream;
stream.flags(std::ios::hex);
stream << unsigned(Character) // uint8_t can be a "char", and we don't want it
// to be treated as such.
<< std::flush;
std::string fillWithZeros(stream.str());
while (fillWithZeros.size() < 2)
fillWithZeros = "0" + fillWithZeros;
return reverseOrderOfBytes(fillWithZeros);
}
std::string getCharVectorRepresentationOfInteger16(uint16_t Integer16) {
std::stringstream stream;
stream.flags(std::ios::hex);
stream << Integer16 << std::flush;
std::string fillWithZeros(stream.str());
while (fillWithZeros.size() < 4)
fillWithZeros = "0" + fillWithZeros;
return reverseOrderOfBytes(fillWithZeros);
}
std::string getCharVectorRepresentationOfInteger32(uint32_t Integer32) {
std::stringstream stream;
stream.flags(std::ios::hex);
stream << Integer32 << std::flush;
std::string fillWithZeros(stream.str());
while (fillWithZeros.size() < 8)
fillWithZeros = "0" + fillWithZeros;
return reverseOrderOfBytes(fillWithZeros);
}
std::string getCharVectorRepresentationOfInteger64(uint64_t Integer64) {
std::stringstream stream;
stream.flags(std::ios::hex);
stream << Integer64 << std::flush;
std::string fillWithZeros(stream.str());
while (fillWithZeros.size() < 16)
fillWithZeros = "0" + fillWithZeros;
return reverseOrderOfBytes(fillWithZeros);
}
std::string getCharVectorRepresentationOfDecimal32(float Decimal32) {
std::stringstream stream;
stream.flags(std::ios::hex);
// https://discord.com/channels/172018499005317120/172018499005317120/807361535193776138
uint32_t Integer32;
std::memcpy(&Integer32, &Decimal32, sizeof(float));
stream << Integer32 << std::flush;
std::string fillWithZeros(stream.str());
while (fillWithZeros.size() < 8)
fillWithZeros = "0" + fillWithZeros;
return reverseOrderOfBytes(fillWithZeros);
}
std::string getCharVectorRepresentationOfDecimal64(double Decimal64) {
std::stringstream stream;
stream.flags(std::ios::hex);
// https://discord.com/channels/172018499005317120/172018499005317120/807361535193776138
uint64_t Integer64;
std::memcpy(&Integer64, &Decimal64, sizeof(double));
stream << Integer64 << std::flush;
std::string fillWithZeros(stream.str());
while (fillWithZeros.size() < 16)
fillWithZeros = "0" + fillWithZeros;
return reverseOrderOfBytes(fillWithZeros);
}