diff options
-rw-r--r-- | src/s2wasm.h | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h index e6782a284..7f3a12360 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -35,6 +35,14 @@ private: } } + bool skipComma() { + skipWhitespace(); + if (*s != ',') return false; + s++; + skipWhitespace(); + return true; + } + void findComma() { while (*s && *s != ',') s++; s++; @@ -66,6 +74,10 @@ private: std::cerr << text << "\n==========\n" << s << "\n==========\n"; } + void unget(Name str) { + s -= strlen(str.str); + } + Name getStr() { std::string str; while (*s && !isspace(*s)) { @@ -75,6 +87,22 @@ private: return cashew::IString(str.c_str(), false); } + Name getCommaSeparated() { + skipWhitespace(); + std::string str; + while (*s && *s != ',') { + str += *s; + s++; + } + skipWhitespace(); + return cashew::IString(str.c_str(), false); + } + + Name getAssign() { + if (match("$discard=")) return Name(); + findComma(); + } + WasmType getType() { if (match("i32")) return i32; if (match("i64")) return i64; @@ -140,11 +168,15 @@ private: mustMatch(name.str); mustMatch(":"); auto func = allocator.alloc<Function>(); + std::map<Name, WasmType> localTypes; // params and result while (1) { if (match(".param")) { while (1) { - func->params.emplace_back(getNextId(), getType()); + Name name = getNextId(); + WasmType type = getType(); + func->params.emplace_back(name, type); + localTypes[name] = type; skipWhitespace(); if (!match(",")) break; } @@ -164,6 +196,24 @@ private: stack.pop_back(); return ret; }; + auto getInput = [&]() { + if (match("$pop")) { + while (isdigit(*s)) s++; + return pop(); + } else { + auto curr = allocator.alloc<GetLocal>(); + curr->name = getStr(); + curr->type = localTypes[curr->name]; + return (Expression*)curr; + } + }; + auto setOutput = [&](Expression* curr, Name assign) { + if (assign.is()) { + stack.push_back(curr); + } else { + currBlock->list.push_back(curr); + } + }; while (1) { skipWhitespace(); if (match("i32.")) { @@ -181,6 +231,17 @@ private: push(parseConst(getStr(), i32, allocator)); } } + } else if (match("call")) { + Name assign = getCommaSeparated(); + skipComma(); + auto curr = allocator.alloc<Call>(); + curr->target = getCommaSeparated(); + while (1) { + if (!skipComma()) break; + curr->operands.push_back(getInput()); + } + std::reverse(curr->operands.begin(), curr->operands.end()); + setOutput(curr, assign); } else if (match("return")) { Block *temp; if (!(func->body && (temp = func->body->dyn_cast<Block>()) && temp->name == FAKE_RETURN)) { @@ -204,7 +265,7 @@ private: wasm.addFunction(func); return; // the function is done } else { - break; + abort_on("function element"); } } } |