diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-03 14:07:09 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-03 14:07:09 -0800 |
commit | 679a41cce15def601a57a88ced7e8ee03b59b8df (patch) | |
tree | 10c22233876d19b79f82f70df64bf2184a3bc139 | |
parent | 5b30873eb082df02a79e7daa2f3aa8b59dab358a (diff) | |
download | binaryen-679a41cce15def601a57a88ced7e8ee03b59b8df.tar.gz binaryen-679a41cce15def601a57a88ced7e8ee03b59b8df.tar.bz2 binaryen-679a41cce15def601a57a88ced7e8ee03b59b8df.zip |
start work on shell and sexpr parser
-rw-r--r-- | src/wasm-sexpr-parser.h | 149 | ||||
-rw-r--r-- | src/wasm-shell.cpp | 5 |
2 files changed, 154 insertions, 0 deletions
diff --git a/src/wasm-sexpr-parser.h b/src/wasm-sexpr-parser.h new file mode 100644 index 000000000..c36311797 --- /dev/null +++ b/src/wasm-sexpr-parser.h @@ -0,0 +1,149 @@ + +// +// Parses WebAssembly code in S-Expression format, as in .wast files. +// + +#include "wasm.h" +#include "mixed_arena.h" + +namespace wasm { + +// Globals + +IString MODULE("module"), + FUNC("func"); + +// +// Generic S-Expression parsing into lists +// + +class SExpressionParser { + char* input; + + MixedArena allocator; + +public: + // Assumes control of and modifies the input. + SExpressionParser(char* input) : input(input) {} + + struct List; + + // A list of Elements, or a string + class Element { + bool isList; + union { + List list_; + IString str_; + }; + + public: + Element() : isList(true) {} + + // list methods + + List& list() { + assert(isList); + return list_; + } + + // string methods + + IString str() { + assert(!isList); + return str_; + } + + Element* setString(IString str__) { + isList = false; + str_ = str__; + return this; + } + + }; + + typedef std::vector<Element*> List; + + Element* parseEverything() { + return parseInnerList(); + } + +private: + // parses the internal part of a list, inside the parens. + Element* parseInnerList() { + if (input[0] == ';') { + // comment + input++; + input = strchr(input, ";)"); + assert(input); + return nullptr; + } + auto ret = allocator.alloc<Element>()->setList(); + while (1) { + Element* curr = parse(); + if (!curr) return ret; + curr->list().push_back(curr); + } + } + + Element* parse() { + skipWhitespace(input); + if (!input) return nullptr; + if (input[0] == '(') { + // a list + input++; + auto ret = parseInnerList(); + skipWhitespace(input); + assert(input[0] == ')'; + input++; + return ret; + } + return parseString(); + } + + void skipWhitespace() { + while (isspace(input[0])) input++; + } + + Element* parseString() { + char *start = input; + while (isalnum(input[0]) || input[0] == '_' || input[0] == '$') input++; + return allocator.alloc<Element>()->setString(IString(start, false)); // TODO: reuse the string here, carefully + } +}; + +// +// SExpressions => WebAssembly module +// + +class SExpressionWasmBuilder { + Module& wasm; + + MixedArena allocator; + SExpressionParser parser; + +public: + // Assumes control of and modifies the input. + SExpressionWasmBuilder(Module& wasm, char* input) : wasm(wasm), parser(input) {} + + void parse() { + Element* root = parser.parseEverything(); + assert(root); + assert(root->list()[0]->str() == MODULE); + for (unsigned i = 1; i < root->list().size(); i++) { + parseModuleElement(root->list()[i]); + } + } + + void parseModuleElement(Element* curr) { + IString id = curr->list()[0]->str(); + if (id == FUNC) return parseFunction(curr); + std::cerr << "bad module element " << id.str << '\n'; + abort(); + } + + void parseFunction(Element* curr) { + } +}; + +} // namespace wasm + diff --git a/src/wasm-shell.cpp b/src/wasm-shell.cpp new file mode 100644 index 000000000..6b5bb942c --- /dev/null +++ b/src/wasm-shell.cpp @@ -0,0 +1,5 @@ + +// +// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format) and executes it. +// + |