summaryrefslogtreecommitdiff
path: root/src/parsing.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/parsing.h')
-rw-r--r--src/parsing.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/parsing.h b/src/parsing.h
new file mode 100644
index 000000000..59e8fc5ae
--- /dev/null
+++ b/src/parsing.h
@@ -0,0 +1,153 @@
+
+#include <sstream>
+
+#include "wasm.h"
+#include "shared-constants.h"
+#include "mixed_arena.h"
+
+namespace wasm {
+
+Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allocator) {
+ const char *str = s.str;
+ auto ret = allocator.alloc<Const>();
+ ret->type = ret->value.type = type;
+ if (isWasmTypeFloat(type)) {
+ if (s == INFINITY_) {
+ switch (type) {
+ case f32: ret->value.f32 = std::numeric_limits<float>::infinity(); break;
+ case f64: ret->value.f64 = std::numeric_limits<double>::infinity(); break;
+ default: return nullptr;
+ }
+ //std::cerr << "make constant " << str << " ==> " << ret->value << '\n';
+ return ret;
+ }
+ if (s == NEG_INFINITY) {
+ switch (type) {
+ case f32: ret->value.f32 = -std::numeric_limits<float>::infinity(); break;
+ case f64: ret->value.f64 = -std::numeric_limits<double>::infinity(); break;
+ default: return nullptr;
+ }
+ //std::cerr << "make constant " << str << " ==> " << ret->value << '\n';
+ return ret;
+ }
+ if (s == NAN_) {
+ switch (type) {
+ case f32: ret->value.f32 = std::nan(""); break;
+ case f64: ret->value.f64 = std::nan(""); break;
+ default: return nullptr;
+ }
+ //std::cerr << "make constant " << str << " ==> " << ret->value << '\n';
+ return ret;
+ }
+ bool negative = str[0] == '-';
+ const char *positive = negative ? str + 1 : str;
+ if (positive[0] == '+') positive++;
+ if (positive[0] == 'n' && positive[1] == 'a' && positive[2] == 'n') {
+ const char * modifier = positive[3] == ':' ? positive + 4 : nullptr;
+ assert(modifier ? positive[4] == '0' && positive[5] == 'x' : 1);
+ switch (type) {
+ case f32: {
+ union {
+ uint32_t pattern;
+ float f;
+ } u;
+ if (modifier) {
+ std::istringstream istr(modifier);
+ istr >> std::hex >> u.pattern;
+ u.pattern |= 0x7f800000;
+ } else {
+ u.pattern = 0x7fc00000;
+ }
+ if (negative) u.pattern |= 0x80000000;
+ if (!isnan(u.f)) u.pattern |= 1;
+ assert(isnan(u.f));
+ ret->value.f32 = u.f;
+ break;
+ }
+ case f64: {
+ union {
+ uint64_t pattern;
+ double d;
+ } u;
+ if (modifier) {
+ std::istringstream istr(modifier);
+ istr >> std::hex >> u.pattern;
+ u.pattern |= 0x7ff0000000000000LL;
+ } else {
+ u.pattern = 0x7ff8000000000000L;
+ }
+ if (negative) u.pattern |= 0x8000000000000000LL;
+ if (!isnan(u.d)) u.pattern |= 1;
+ assert(isnan(u.d));
+ ret->value.f64 = u.d;
+ break;
+ }
+ default: return nullptr;
+ }
+ //std::cerr << "make constant " << str << " ==> " << ret->value << '\n';
+ return ret;
+ }
+ if (s == NEG_NAN) {
+ switch (type) {
+ case f32: ret->value.f32 = -std::nan(""); break;
+ case f64: ret->value.f64 = -std::nan(""); break;
+ default: return nullptr;
+ }
+ //std::cerr << "make constant " << str << " ==> " << ret->value << '\n';
+ return ret;
+ }
+ }
+ switch (type) {
+ case i32: {
+ if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) {
+ bool negative = str[0] == '-';
+ if (negative) str++;
+ std::istringstream istr(str);
+ uint32_t temp;
+ istr >> std::hex >> temp;
+ ret->value.i32 = negative ? -temp : temp;
+ } else {
+ std::istringstream istr(str);
+ int32_t temp;
+ istr >> temp;
+ ret->value.i32 = temp;
+ }
+ break;
+ }
+ case i64: {
+ if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) {
+ bool negative = str[0] == '-';
+ if (negative) str++;
+ std::istringstream istr(str);
+ uint64_t temp;
+ istr >> std::hex >> temp;
+ ret->value.i64 = negative ? -temp : temp;
+ } else {
+ std::istringstream istr(str);
+ int64_t temp;
+ istr >> temp;
+ ret->value.i64 = temp;
+ }
+ break;
+ }
+ case f32: {
+ char *end;
+ ret->value.f32 = strtof(str, &end);
+ assert(!isnan(ret->value.f32));
+ break;
+ }
+ case f64: {
+ char *end;
+ ret->value.f64 = strtod(str, &end);
+ assert(!isnan(ret->value.f64));
+ break;
+ }
+ default: return nullptr;
+ }
+ //std::cerr << "make constant " << str << " ==> " << ret->value << '\n';
+ return ret;
+}
+
+
+} // namespace wasm
+