summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emscripten-optimizer/istring.h2
-rw-r--r--src/wasm-s-parser.h75
2 files changed, 43 insertions, 34 deletions
diff --git a/src/emscripten-optimizer/istring.h b/src/emscripten-optimizer/istring.h
index abc1e327b..498c7c27c 100644
--- a/src/emscripten-optimizer/istring.h
+++ b/src/emscripten-optimizer/istring.h
@@ -75,10 +75,10 @@ struct IString {
char *copy = (char*)malloc(strlen(s)+1); // XXX leaked
strcpy(copy, s);
s = copy;
+ strings->insert(s);
} else {
s = *existing;
}
- strings->insert(s);
str = s;
}
}
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index db57dda9f..bb3492e9a 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -125,47 +125,37 @@ public:
SExpressionParser(char* input) : input(input) {
root = nullptr;
while (!root) { // keep parsing until we pass an initial comment
- root = parseInnerList();
+ root = parse();
}
}
Element* root;
private:
- // parses the internal part of a list, inside the parens.
- Element* parseInnerList() {
- if (input[0] == ';') {
- // comment
- input++;
- if (input[0] == ';') {
- while (input[0] != '\n') input++;
- return nullptr;
- }
- input = strstr(input, ";)");
- assert(input);
- return nullptr;
- }
- auto ret = allocator.alloc<Element>();
- while (1) {
- Element* curr = parse();
- if (!curr) return ret;
- ret->list().push_back(curr);
- }
- }
-
Element* parse() {
- skipWhitespace();
- if (input[0] == 0 || input[0] == ')') return nullptr;
- if (input[0] == '(') {
- // a list
- input++;
- auto ret = parseInnerList();
+ std::vector<Element *> stack;
+ Element *curr = allocator.alloc<Element>();
+ while (1) {
skipWhitespace();
- assert(input[0] == ')');
- input++;
- return ret;
+ if (input[0] == 0)
+ break;
+ if (input[0] == '(') {
+ input++;
+ stack.push_back(curr);
+ curr = allocator.alloc<Element>();
+ } else if (input[0] == ')') {
+ input++;
+ auto last = curr;
+ curr = stack.back();
+ assert(stack.size());
+ stack.pop_back();
+ curr->list().push_back(last);
+ } else {
+ curr->list().push_back(parseString());
+ }
}
- return parseString();
+ assert(stack.size() == 0);
+ return curr;
}
void skipWhitespace() {
@@ -174,7 +164,26 @@ private:
if (input[0] == ';' && input[1] == ';') {
while (input[0] && input[0] != '\n') input++;
} else if (input[0] == '(' && input[1] == ';') {
- input = strstr(input, ";)") + 2;
+ // Skip nested block comments.
+ input += 2;
+ int depth = 1;
+ while (1) {
+ if (input[0] == 0) {
+ return;
+ }
+ if (input[0] == '(' && input[1] == ';') {
+ input += 2;
+ depth++;
+ } else if (input[0] == ';' && input[1] == ')') {
+ input += 2;
+ --depth;
+ if (depth == 0) {
+ break;
+ }
+ } else {
+ input++;
+ }
+ }
} else {
return;
}